如何讀寫BMP圖像



由於BMP格式的圖像簡單,讀寫BMP圖的實現也相對容易,所以在構建自己的圖像處理庫的時候,都是使用BMP作爲測試圖像。首先說一BMP圖像相關的知識。


BMP圖像的組成

BMP圖像由4個部分組成:

  1. 文件頭:BITMAPFILEHEADER(14字節)
  2. 信息頭:BITMAPINFOHEADER(40字節)
  3. 顏色表:RGBQUAD(8位的爲1024字節)(小於24位的圖有,24位沒有)
  4. 圖像數據

文件頭 BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER 
{ 
WORD  bfType; //位圖文件的類型,該值必需是0x4D42,也就是字符'BM'。 
DWORD bfSize; //位圖文件大小:文件頭+信息頭+顏色表+數據部分
WORD  bfReserved1; //保留字,爲0,留做擴展,對實際的解碼格式沒有影響。
WORD  bfReserved2; //同上 
DWORD bfOffBits; //位圖文件頭到圖像數據的偏移量,以字節爲單位
} BITMAPFILEHEADER;
這個結構的長度是固定的,爲14個字節(WORD爲無符號16位整數,DWORD爲無符號32位整數)。該結果體作爲文件存儲的時候用。

結構體的定義參考Windows.h

信息頭BITMAPINFOHEADER

這部分告訴應用程序圖像的詳細信息,在屏幕上顯示圖像將會使用這些信息,它從文件的第15個字節開始。
typedef struct tagBITMAPINFOHEADER 
{
DWORD biSize; //BITMAPINFOHEADER結構大小,字節爲單位 
LONG biWidth; //寬度(以像素爲單位,不是每行字節數!!)
LONG biHeight; //高度(以像素爲單位)
WORD biPlanes; //目標設備的級別,必須爲1 
WORD biBitCount; //顏色深度,每個像素所需要的位數
DWORD biCompression; //位圖的壓縮類型
DWORD biSizeImage; //位圖數據部分的大小,以字節爲單位(4字節對齊)
LONG biXPelsPerMeter; //位圖水平分辨率,每米像素數
LONG biYPelsPerMeter; //位圖垂直分辨率,每米像素數
DWORD biClrUsed; //位圖實際使用的顏色表中的顏色數
DWORD biClrImportant; //位圖顯示過程中重要的顏色數
} BITMAPINFOHEADER;

該結構體大小爲40字節。

顏色表RGBQUAD

BMP只能存儲單色(1位),16色(4位),256色(8位),和真彩色(24位)4種格式的數據,只有真彩色沒有調色板(顏色表)。

8位的BMP中,每個像素的數值就是顏色表數組的下標。而24位的BMP圖,每個像素的數值就是表示實際的像素值。

typedef struct tagRGBQUAD {
  BYTE    rgbBlue; 
  BYTE    rgbGreen; 
  BYTE    rgbRed; 
  BYTE    rgbReserved; 
} RGBQUAD;

圖像數據

在8位BMP中,每個像素8位,存放的是顏色表的索引,24位每個像素24位,存放的是實際顏色的值,分爲三個通道BGR。

要注意兩點:

(1) 每一行的字節數必須是4的整倍數,如果不是,則需要補齊。也就是4字節對齊。
(2) bmp文件的數據從下到上,從左到右的。也就是說,從文件中最先讀到的是圖象最下面一行的左邊第一個像素,然後是左邊第二個像素……接下來是倒數第二行左邊第一個像素,左邊第二個像素……依次類推 ,最後得到的是最上面一行的最右一個像素。


具體實現

Github:https://github.com/qianqing13579/QQImageProcess
其中的Bmp.h和Bmp.cpp包含了讀寫BMP圖像的具體實現
可以先執行ImageProcessTest類中的TestReadAndWrite()測試用例,看一下使用方法

2017-1-10 18:35:33


非常感謝您的閱讀,如果您覺得這篇文章對您有幫助,歡迎掃碼進行讚賞。
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章