BMP的4個組成部分: 1.文件頭信息塊
typedef struct tagBITMAPFILEHEADER // bmfh { WORD bfType ; // signature word "BM" or 0x4D42 DWORD bfSize ; // entire size of file WORD bfReserved1 ; // must be zero WORD bfReserved2 ; // must be zero DWORD bfOffsetBits ; // offset in file of DIB pixel bits } BITMAPFILEHEADER, * PBITMAPFILEHEADER ;
0000-0001:文件標(biāo)識,為字母ASCII碼“BM”。 0002-0005:文件大小。 0006-0009:保留,每字節(jié)以“00”填寫。 000A-000D:記錄圖像數(shù)據(jù)區(qū)的起始位置。
各字節(jié)的信息依次含義為:文件頭信息塊大小,圖像描述信息塊的大小,圖像顏色表的大小,保留(為01)。 2.圖像描述信息塊
000E-0011:圖像描述信息塊的大小,常為28H。 0012-0015:圖像寬度。 0016-0019:圖像高度。 001A-001B:圖像的plane總數(shù)(恒為1)。 001C-001D:記錄像素的位數(shù),很重要的數(shù)值,圖像的顏色數(shù)由該值決定。 001E-0021:數(shù)據(jù)壓縮方式(數(shù)值位0:不壓縮;1:8位壓縮;2:4位壓縮)。 0022-0025:圖像區(qū)數(shù)據(jù)的大小。 0026-0029:水平每米有多少像素,在設(shè)備無關(guān)位圖(.DIB)中,每字節(jié)以00H填寫。 002A-002D:垂直每米有多少像素,在設(shè)備無關(guān)位圖(.DIB)中,每字節(jié)以00H填寫。 002E-0031:此圖像所用的顏色數(shù),如值為0,表示所有顏色一樣重要。 3.顏色表 顏色表的大小根據(jù)所使用的顏色模式而定:
2色圖像為8字節(jié);16色圖像位64字節(jié);256色圖像為1024字節(jié)。
其中,每4字節(jié)表示一種顏色,并以B(藍色)、G(綠色)、R(紅色)、alpha(32位位圖的透明度值,一般不需要)。
即首先4字節(jié)表示顏色號0的顏色,接下來表示顏色號1的顏色,依此類推。 4.圖像數(shù)據(jù)區(qū) 顏色表接下來位為位圖文件的圖像數(shù)據(jù)區(qū),在此部分記錄著每點像素對應(yīng)的顏色號,其記錄方式也隨顏色模式而定,
既2色圖像每點占1位(8位為1字節(jié));16色圖像每點占4位(半字節(jié));256色圖像每點占8位(1字節(jié));真彩色圖像每點占24位(3字節(jié))。
所以,整個數(shù)據(jù)區(qū)的大小也會隨之變化。
究其規(guī)律而言,可的出如下計算公式:圖像數(shù)據(jù)信息大小=(圖像寬度*圖像高度*記錄像素的位數(shù))/8。 然而,未壓縮的圖像信息區(qū)的大小。除了真彩色模式外,其余的均大于或等于數(shù)據(jù)信息的大小。這是為什么呢?原因有兩個: 1.BMP文件記錄一行圖像是以字節(jié)為單位的。因此,就不存在一個字節(jié)中的數(shù)據(jù)位信息表示的點在不同的兩行中。
也就是說,設(shè)顯示模式位16色,在每個字節(jié)分配兩個點信息時,如果圖像的寬度位奇數(shù),
那么最后一個像素點的信息將獨占一個字節(jié),這個字節(jié)的后4位將沒有意義。接下來的一個字節(jié)將開始記錄下一行的信息。 2.為了顯示的方便,除了真彩色外,其他的每中顏色模式的行字節(jié)數(shù)要用數(shù)據(jù)“00”補齊為4的整數(shù)倍。
如果顯示模式為16色,當(dāng)圖像寬為19時,存儲時每行則要補充4-(19/2+1)%4=2個字節(jié)(加1是因為里面有一個像素點要獨占了一字節(jié))。
如果顯示模式為256色,當(dāng)圖像寬為19時,每行也要補充4-19%4=1個字節(jié) bfType 文件標(biāo)識 2bytes 0000-0001 42 4d bfSize 文件大小 1dword 0002-0005 3a 00 00 00 bfReserved1 bfReserved1 保留 1dword 0006-0009 00 00 00 00 bfOffBits 數(shù)據(jù)起始位置 1dword 000a-000d 36 00 00 00 biSize 圖像信息頭長度 1dword 000e-0011 28 00 00 00 biWidth 位圖的寬度 1dword 0012-0015 01 00 00 00 biHeight 位圖的高度 1dword 0016-0019 00 01 00 00 biPlanes 位圖的位面數(shù) 1word 001A-001B 01 00 biBitCount 像素的位數(shù) 1word 001C-001D 18 00 biCompression 數(shù)據(jù)壓縮方式 1dword 001E-0021 00 00 00 00 biSizeImage 圖像區(qū)數(shù)據(jù)大小 1dword 0022-0025 04 00 00 00 biXPelsPerMeter 水平像素/米 1dword 0026-0029 00 00 00 00 biYPelsPerMeter 垂直像素/米 1dword 002A-002D 00 00 00 00 biClrUsed 使用的顏色數(shù) 1dword 002E-0031 00 00 00 00 biClrImportant 重要的顏色數(shù) 1dword 0032-0035 00 00 00 00 調(diào)色板規(guī)范 N*4byte 圖像數(shù)據(jù) Xbytes
構(gòu)件詳解
1. 位圖文件頭
位圖文件頭包含有關(guān)于文件類型、文件大小、存放位置等信息,在Windows 3.0以上版本的位圖文件中用BITMAPFILEHEADER結(jié)構(gòu)來定義:
typedef struct tagBITMAPFILEHEADER {
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
其中:
bfType
說明文件的類型.(該值必需是0x4D42,也就是字符'BM'。我們不需要判斷OS/2的位圖標(biāo)識,這么做現(xiàn)在來看似乎已經(jīng)沒有什么意義了,而且如果要支持OS/2的位圖,程序?qū)⒆兊煤芊爆?。所以,在此只建議你檢察'BM'標(biāo)識)
bfSize
說明文件的大小,用字節(jié)為單位
bfReserved1
保留,必須設(shè)置為0
bfReserved2
保留,必須設(shè)置為0
bfOffBits
說明從文件頭開始到實際的圖象數(shù)據(jù)之間的字節(jié)的偏移量。這個參數(shù)是非常有用的,因為位圖信息頭和調(diào)色板的長度會根據(jù)不同情況而變化,所以你可以用這個偏移值迅速的從文件中讀取到位數(shù)據(jù)。
2. 位圖信息頭
位圖信息用BITMAPINFO結(jié)構(gòu)來定義,它由位圖信息頭(bitmap-information header)和彩色表(color table)組成,前者用BITMAPINFOHEADER結(jié)構(gòu)定義,后者用RGBQUAD結(jié)構(gòu)定義。BITMAPINFO結(jié)構(gòu)具有如下形式:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
其中:
bmiHeader
說明BITMAPINFOHEADER結(jié)構(gòu),其中包含了有關(guān)位圖的尺寸及位格式等信息
bmiColors
說明彩色表RGBQUAD結(jié)構(gòu)的陣列,其中包含索引圖像的真實RGB值。
BITMAPINFOHEADER結(jié)構(gòu)包含有位圖文件的大小、壓縮類型和顏色格式,其結(jié)構(gòu)定義為:
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
其中:
biSize
說明BITMAPINFOHEADER結(jié)構(gòu)所需要的字?jǐn)?shù)。注:這個值并不一定是BITMAPINFOHEADER結(jié)構(gòu)的尺寸,它也可能是sizeof(BITMAPV4HEADER)的值,或是sizeof(BITMAPV5HEADER)的值。這要根據(jù)該位圖文件的格式版本來決定,不過,就現(xiàn)在的情況來看,絕大多數(shù)的BMP圖像都是BITMAPINFOHEADER結(jié)構(gòu)的(可能是后兩者太新的緣故吧:-)。
biWidth
說明圖象的寬度,以象素為單位
biHeight
說明圖象的高度,以象素為單位。注:這個值除了用于描述圖像的高度之外,它還有另一個用處,就是指明該圖像是倒向的位圖,還是正向的位圖。如果該值是一個正數(shù),說明圖像是倒向的,如果該值是一個負數(shù),則說明圖像是正向的。大多數(shù)的BMP文件都是倒向的位圖,也就是時,高度值是一個正數(shù)。(注:當(dāng)高度值是一個負數(shù)時(正向圖像),圖像將不能被壓縮(也就是說biCompression成員將不能是BI_RLE8或BI_RLE4)。
biPlanes
為目標(biāo)設(shè)備說明位面數(shù),其值將總是被設(shè)為1
biBitCount
說明比特數(shù)/象素,其值為1、4、8、16、24、或32
biCompression
說明圖象數(shù)據(jù)壓縮的類型。其值可以是下述值之一:
BI_RGB:沒有壓縮;
BI_RLE8:每個象素8比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成(重復(fù)象素計數(shù)和顏色索引);
BI_RLE4:每個象素4比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成
BI_BITFIELDS:每個象素的比特由指定的掩碼決定。
biSizeImage
說明圖象的大小,以字節(jié)為單位。當(dāng)用BI_RGB格式時,可設(shè)置為0
biXPelsPerMeter
說明水平分辨率,用象素/米表示
biYPelsPerMeter
說明垂直分辨率,用象素/米表示
biClrUsed
說明位圖實際使用的彩色表中的顏色索引數(shù)(設(shè)為0的話,則說明使用所有調(diào)色板項)
biClrImportant
說明對圖象顯示有重要影響的顏色索引的數(shù)目,如果是0,表示都重要。
現(xiàn)就BITMAPINFOHEADER結(jié)構(gòu)作如下說明:
(1) 彩色表的定位
應(yīng)用程序可使用存儲在biSize成員中的信息來查找在BITMAPINFO結(jié)構(gòu)中的彩色表,如下所示:
pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))
(2) biBitCount
biBitCount=1 表示位圖最多有兩種顏色,缺省情況下是黑色和白色,你也可以自己定義這兩種顏色。圖像信息頭裝調(diào)色板中將有兩個調(diào)色板項,稱為索引0和索引1。圖象數(shù)據(jù)陣列中的每一位表示一個象素。如果一個位是0,顯示時就使用索引0的RGB值,如果位是1,則使用索引1的RGB值。
biBitCount=4 表示位圖最多有16種顏色。每個象素用4位表示,并用這4位作為彩色表的表項來查找該象素的顏色。例如,如果位圖中的第一個字節(jié)為0x1F,它表示有兩個象素,第一象素的顏色就在彩色表的第2表項中查找,而第二個象素的顏色就在彩色表的第16表項中查找。此時,調(diào)色板中缺省情況下會有16個RGB項。對應(yīng)于索引0到索引15。
biBitCount=8 表示位圖最多有256種顏色。每個象素用8位表示,并用這8位作為彩色表的表項來查找該象素的顏色。例如,如果位圖中的第一個字節(jié)為0x1F,這個象素的顏色就在彩色表的第32表項中查找。此時,缺省情況下,調(diào)色板中會有256個RGB項,對應(yīng)于索引0到索引255。
biBitCount=16 表示位圖最多有216種顏色。每個色素用16位(2個字節(jié))表示。這種格式叫作高彩色,或叫增強型16位色,或64K色。它的情況比較復(fù)雜,當(dāng)biCompression成員的值是BI_RGB時,它沒有調(diào)色板。16位中,最低的5位表示藍色分量,中間的5位表示綠色分量,高的5位表示紅色分量,一共占用了15位,最高的一位保留,設(shè)為0。這種格式也被稱作555 16位位圖。如果biCompression成員的值是BI_BITFIELDS,那么情況就復(fù)雜了,首先是原來調(diào)色板的位置被三個DWORD變量占據(jù),稱為紅、綠、藍掩碼。分別用于描述紅、綠、藍分量在16位中所占的位置。在Windows 95(或98)中,系統(tǒng)可接受兩種格式的位域:555和565,在555格式下,紅、綠、藍的掩碼分別是:0x7C00、0x03E0、0x001F,而在565格式下,它們則分別為:0xF800、0x07E0、0x001F。你在讀取一個像素之后,可以分別用掩碼“與”上像素值,從而提取出想要的顏色分量(當(dāng)然還要再經(jīng)過適當(dāng)?shù)淖笥乙撇僮鳎?。在NT系統(tǒng)中,則沒有格式限制,只不過要求掩碼之間不能有重疊。(注:這種格式的圖像使用起來是比較麻煩的,不過因為它的顯示效果接近于真彩,而圖像數(shù)據(jù)又比真彩圖像小的多,所以,它更多的被用于游戲軟件)。
biBitCount=24 表示位圖最多有224種顏色。這種位圖沒有調(diào)色板(bmiColors成員尺寸為0),在位數(shù)組中,每3個字節(jié)代表一個象素,分別對應(yīng)于顏色R、G、B。
biBitCount=32 表示位圖最多有232種顏色。這種位圖的結(jié)構(gòu)與16位位圖結(jié)構(gòu)非常類似,當(dāng)biCompression成員的值是BI_RGB時,它也沒有調(diào)色板,32位中有24位用于存放RGB值,順序是:最高位—保留,紅8位、綠8位、藍8位。這種格式也被成為888 32位圖。如果 biCompression成員的值是BI_BITFIELDS時,原來調(diào)色板的位置將被三個DWORD變量占據(jù),成為紅、綠、藍掩碼,分別用于描述紅、綠、藍分量在32位中所占的位置。在Windows 95(or 98)中,系統(tǒng)只接受888格式,也就是說三個掩碼的值將只能是:0xFF0000、0xFF00、0xFF。而在NT系統(tǒng)中,你只要注意使掩碼之間不產(chǎn)生重疊就行。(注:這種圖像格式比較規(guī)整,因為它是DWORD對齊的,所以在內(nèi)存中進行圖像處理時可進行匯編級的代碼優(yōu)化(簡單))。
1像素24色紅色背景圖片 bfType 文件標(biāo)識 2bytes 0000-0001 42 4d bfSize 文件大小 1dword 0002-0005 3a 00 00 00 bfReserved1 bfReserved1 保留 1dword 0006-0009 00 00 00 00 bfOffBits 數(shù)據(jù)起始位置 1dword 000a-000d 36 00 00 00 biSize 圖像信息頭長度 1dword 000e-0011 28 00 00 00 biWidth 位圖的寬度 1dword 0012-0015 01 00 00 00 biHeight 位圖的高度 1dword 0016-0019 00 01 00 00 biPlanes 位圖的位面數(shù) 1word 001A-001B 01 00 biBitCount 像素的位數(shù) 1word 001C-001D 18 00 biCompression 數(shù)據(jù)壓縮方式 1dword 001E-0021 00 00 00 00 biSizeImage 圖像區(qū)數(shù)據(jù)大小 1dword 0022-0025 04 00 00 00 biXPelsPerMeter 水平像素/米 1dword 0026-0029 00 00 00 00 biYPelsPerMeter 垂直像素/米 1dword 002A-002D 00 00 00 00 biClrUsed 使用的顏色數(shù) 1dword 002E-0031 00 00 00 00 biClrImportant 重要的顏色數(shù) 1dword 0032-0035 00 00 00 00 調(diào)色版規(guī)范 0byte 忽略 圖像數(shù)據(jù) 3bytes 0036-0038 00 00-FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 白色1x1 42 4D 3A 00 00 00 00 00-00 00 36 00 00 00 28 00 00 00 01 00 00 00 01 00-00 00 01 00 18 00 00 00 00 00 04 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF-FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 紅色1x1 42 4D 3A 00 00 00 00 00-00 00 36 00 00 00 28 00 00 00 01 00 00 00 01 00-00 00 01 00 18 00 00 00 00 00 04 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 紅色2x2 42 4D 46 00 00 00 00 00-00 00 36 00 00 00 28 00 00 00 02 00 00 00 02 00-00 00 01 00 18 00 00 00 00 00 10 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-FF 00 00 FF 00 00 00 00 FF 00 00 FF 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00