##没有躲过的坑--获取一张图片的width和height
有时候问题总是被想的过于复杂!
简单说就是读取一张图片,然后得到这个图片的width和height。
首先,用到的库没有Image这个控件,所以不能从控件获得图片的高和宽。
于是GOOGLE了一个算法,稍作修改,对于不同的类型有不同的计算方法,上代码吧:
~~~
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
string fname = "D:\\暴走.png";
ifstream ffin(fname, std::ios::binary);
if (!ffin) {
cout << "Can not open this file." << endl;
return 0;
}
int image_type = 0;
char c = fname.at(fname.length() - 1);
char c2 = fname.at(fname.length() - 3);
if ((c == 'f') && (c2 == 'g')) { // file extension name is gif
image_type = 1;
}
else if ((c == 'g') && (c2 == 'j')) { // file extension name is jpg
image_type = 2;
}
else if ((c == 'g') && (c2 == 'p')) { // file extension name is png
image_type = 3;
}
else if ((c == 'p') && (c2 == 'b')) { // file extension name is bmp
image_type = 4;
}
char s1[2] = { 0 };
char s2[2] = { 0 };
long m_Width = 0;
long m_Height = 0;
switch (image_type)
{
case 1: // gif
ffin.seekg(6);
ffin.read(s1, 2);
ffin.read(s2, 2);
m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
break;
case 2: // jpg
ffin.seekg(164);
ffin.read(s1, 2);
ffin.read(s2, 2);
m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
break;
case 3: // png
ffin.seekg(17);
ffin.read(s1, 2);
ffin.seekg(2, std::ios::cur);
ffin.read(s2, 2);
m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
break;
case 4: // bmp
ffin.seekg(18);
ffin.read(s1, 2);
ffin.seekg(2, std::ios::cur);
ffin.read(s2, 2);
m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
break;
default:
cout << "NO" << endl;
break;
}
ffin.close();
cout << "width:" << m_Width << endl;
cout << "height:" << m_Height << endl;
}
~~~
上述代码的优点就是,不用读取整个图片的大小,效率是很高的。
但是,有一个很大的坑,就是无法计算出小于24kb的图片,这不是坑爹的吗?
咨询了一下其他平台的做法,用了一个叫ImageMagic的库,用于图片的处理很强大。配置了好久,但是还是会报错。也许跟vs编译器的版本有关吧。况且为了一个小小的功能就引入一个库,未免有点小题大做了。
蓦然回首,CImage类正等着呢!
原来忘记了最基本的windows GDI了。
好吧,别忘了,引入头文件:
~~~
#include<iostream>
#include<atlimage.h>
int main()
{
CImage m;
std::wstring imgPath = _T("d:\\222.png");
m.Load(imgPath.c_str());
std::cout << m.GetWidth() << std::endl;
return 0;
}
~~~
没有躲过的坑儿–我们忽略那些微小而基本的功能!
- 前言
- deprecated关键字
- 指针(内存泄露)
- 头文件相互包含(Compiler error C2653: not a class or namespace name)
- 获取一张图片的width和height
- This function or variable may be unsafe.
- 智能指针陷阱
- wstring与string的转换
- windows下chrome浏览器插件不能安装
- 重定义关键字
- 正确释放vector的内存
- 获取设备环境HDC
- 抽象类不能实例化对象(但是你明明定义的不是抽象类)
- 重载赋值运算符的自我赋值
- 程序中的变量未初始化
- 成对使用new和delete时要采取相同的形式
- 意想不到的除数为零
- map的初始化(插入数据)
- 正则表达式截取字符串
- 捕获窗口之外的鼠标消息(钩子还是??)
- 类中的静态成员变量(static or const static)
- 有if就要有else(一定成对)
- map查找结果处理
- 使用using namespace std的坏习惯
- new一个指针数组、以及创建动态二维数组
- 使用太多的全局变量
- 没有及时break出for循环
- vector使用erase后迭代器变成野指针
- C++函数的默认参数(重新定义默认参数)
- 0xC0000005: 读取位置 xxx时发生访问冲突
- std::string初始化、最快速判断字符串为空
- 你开发的软件安装在C盘Program Files (x86)下产生的异常