源:bitmap格式分析html
參考:bitmap圖像介紹算法
最近正在着手開發一個圖片庫,也就是實現對常見圖片格式的度寫操做。做爲總結與積累,我會把這些圖片格式以及加載的實現寫在個人Blog上。測試
塊名稱
|
對應Windows結構體定義
|
大小(Byte)
|
文件信息頭
|
BITMAPFILEHEADER
|
14
|
位圖信息頭
|
BITMAPINFOHEADER
|
40
|
RGB顏色陣列
|
BYTE*
|
由圖像長寬尺寸決定
|
typedef struct tagBITMAPFILEHEADER { /* bmfh */ UINT bfType; DWORD bfSize; UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER;
其中:spa
bfType
|
說明文件的類型,該值必需是0x4D42,也就是字符'BM'。
|
bfSize
|
說明該位圖文件的大小,用字節爲單位
|
bfReserved1
|
保留,必須設置爲0
|
bfReserved2
|
保留,必須設置爲0
|
bfOffBits
|
說明從文件頭開始到實際的圖象數據之間的字節的偏移量。這個參數是很是有用的,由於位圖信息頭和調色板的長度會根據不一樣狀況而變化,因此你能夠用這個偏移值迅速的從文件中讀取到位數據。
|
typedef struct tagBITMAPINFOHEADER { /* bmih */ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER;
其中:code
biSize
|
說明BITMAPINFOHEADER結構所須要的字數。
|
biWidth
|
說明圖象的寬度,以象素爲單位。
|
biHeight
|
說明圖象的高度,以象素爲單位。注:這個值除了用於描述圖像的高度以外,它還有另外一個用處,就是指明該圖像是倒向的位圖,仍是正向的位圖。若是該值是一個正數,說明圖像是倒向的,若是該值是一個負數,則說明圖像是正向的。大多數的BMP文件都是倒向的位圖,也就是時,高度值是一個正數。
|
biPlanes
|
爲目標設備說明位面數,其值將老是被設爲1。
|
biBitCount
|
說明比特數/象素,其值爲一、四、八、1六、2四、或32。可是因爲咱們平時用到的圖像絕大部分是24位和32位的,因此咱們討論這兩類圖像。
|
biCompression
|
說明圖象數據壓縮的類型,一樣咱們只討論沒有壓縮的類型:BI_RGB。
|
biSizeImage
|
說明圖象的大小,以字節爲單位。當用BI_RGB格式時,可設置爲0。
|
biXPelsPerMeter
|
說明水平分辨率,用象素/米表示。
|
biYPelsPerMeter
|
說明垂直分辨率,用象素/米表示。
|
biClrUsed
|
說明位圖實際使用的彩色表中的顏色索引數(設爲0的話,則說明使用全部調色板項)。
|
biClrImportant
|
說明對圖象顯示有重要影響的顏色索引的數目,若是是0,表示都重要。
|
藍色B值
|
綠色G值
|
紅色R值
|
藍色B值
|
綠色G值
|
紅色R值
|
透明通道A值
|
//Load the file header BITMAPFILEHEADER header; memset(&header, 0, sizeof(header)); inf.read((char*)&header, sizeof(header)); if(header.bfType != 0x4D42) return false;
這個很簡單,沒有什麼好說的。orm
//Load the image information header BITMAPINFOHEADER infoheader; memset(&infoheader, 0, sizeof(infoheader)); inf.read((char*)&infoheader, sizeof(infoheader)); m_iImageWidth = infoheader.biWidth; m_iImageHeight = infoheader.biHeight; m_iBitsPerPixel = infoheader.biBitCount;
這裏咱們獲得了3各重要的圖形屬性:寬,高,以及每一個像素顏色所佔用的位數。視頻
//Calculate the image data size int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 31) >> 5) << 2; m_iImageDataSize = iLineByteCnt * m_iImageHeight;
if(m_pImageData) delete []m_pImageData; m_pImageData = new unsigned char[m_iImageDataSize]; inf.read((char*)m_pImageData, m_iImageDataSize);
若是你足夠細心,就會發現內存m_pImageData裏的數據的確是BGR格式,能夠用個純藍色或者是純紅色的圖片測試一下。htm
void CImage::DrawImage(HDC hdc, int iLeft, int iTop, int iWidth, int iHeight) { if(!hdc || m_pImageData == NULL) return; BITMAPINFO bmi; memset(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFO); bmi.bmiHeader.biWidth = m_iImageWidth; bmi.bmiHeader.biHeight = m_iImageHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = m_iBitsPerPixel; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = m_iImageDataSize; StretchDIBits(hdc, iLeft, iTop, iWidth, iHeight, 0, 0, m_iImageWidth, m_iImageHeight, m_pImageData, &bmi, DIB_RGB_COLORS, SRCCOPY); }