##沒有躲過的坑--獲取一張圖片的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)下產生的異常