這段時間在弄bootloader的啓動logo,其中總要和bitmap打交道,把bitmap的格式記錄如下。
BMP(Bitmap_File)圖形文件是Windows採用的圖形文件格式,在Windows環境下運行的所有圖像處理軟件都支持BMP圖像文件格式。Windows系統內部圖像繪製操作都是以BMP爲基礎的。Windows 3.0以前的BMP文件格式與顯示設備有關,因此把這種BMP圖像文件格式成爲設備相關位圖DDB(device-dependent bitmap)文件格式。Windows 3.0以後的BMP圖像文件與顯示設備無關,因此把這種BMP圖像文件格式稱爲設備無關位圖DIB(device-independent bitmap)格式,目的是爲了讓Windows能夠在任何類型的顯示設備上顯示所存儲的圖像。BMP位圖文件默認的文件擴展名爲BMP或者bmp(有時它也會以.DIB或者.RLE作爲擴展名)。
文件結構:
位圖文件可看成有4個部分組成:位圖文件頭(bitmap-file header),位圖信息頭(bitmap-information header),彩色表(color table)和定義位圖的字節陣列。
1. 位圖文件頭:
包含信息:文件類型,文件大小,存放位置等信息。C 中定義爲如下結構體:
typedef struct tagBITMAPFILEHEADER {
UINT bfType; //說明文件的類型必須是‘BM’。
DWORD bfSize; //說明文件的大小,用字節爲單位
UINT bfReserved1; //保留,但必須爲0
UINT bfReserved2; //保留,但必須爲0
DWORD bfOffBits; //說明從文件頭開始到實際的圖像數據之間的字節的偏移量。這個參數是非常有用的,因爲位圖信息頭和調色板的長度會根據不同情況而變化,所以你可以用這個偏移值迅速的從文件中讀取到數據位。
}BITMAPFILEHEADER;
2. 位圖信息頭:
位圖信息頭(BITMAPINFO)包含位圖信息頭(BITMAPINFOHEADER)和彩色表(RGBQUAD)
Typedef struct tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader; //包含了有關位圖的尺寸及位圖格式等信息
RGBQUAD bmiColors[1];//包含索引圖像的真實RGB值。
} BITMAPINFO;
Typedef struct tagBITMAPINFOHEADER {
DWORD biSize; //說明BITMAPINFOHEADER結構所需要的字數。
LONG biWidth; //說明圖像的寬度,以像素爲單位
LONG biHeight; //說明像素的高度,以像素爲單位
WORD biPlanes; //爲目標設備說明位面數,其值將總是被設爲1
WORD biBitCount; //說明比特數/像素,其值爲1,4,8,16,24,32
DWORD biCompression; //說明壓縮方式
DWORD biSizeImage; //說明圖像大小,以字節爲單位
LONG biXPelsPerMeter; //說明水平分辨率,用象素/米
LONG biYPelsPerMeter; //說明垂直分辨率,用象素/米
DWORD biClrUsed; //說明位圖實際使用的彩色表中的顏色索引數
DWORD biClrImportant; //說明對圖像顯示有重要影響的顏色索引的數目,如果是0,表示都重要。
} BITMAPINFOHEADER;
現就BITMAPINFOHEADER結構作如下說明:
(1) 彩色表的定位
應用程序可使用存儲在biSize成員中的信息來查找在BITMAPINFO結構中的彩色表,如下所示:
pColor = ((LPSTR) pBitmapInfo (WORD) (pBitmapInfo->bmiHeader.biSize))
(2) biBitCount
biBitCount=1 表示位圖最多有兩種顏色,缺省情況下是黑色和白色,你也可以自己定義這兩種顏色。圖像信息頭裝調色板中將有兩個調色板項,稱爲索引0和索引1。圖象數據陣列中的每一位表示一個象素。如果一個位是0,顯示時就使用索引0的RGB值,如果位是1,則使用索引1的RGB值。
biBitCount=4 表示位圖最多有16種顏色。每個象素用4位表示,並用這4位作爲彩色表的表項來查找該象素的顏色。 例如,如果位圖中的第一個字節爲0x1F,它表示有兩個象素,第一象素的顏色就在彩色表的第2表項中查找,而第二個象素的顏色就在彩色表的第16表項中查找。此時,調色板中缺省情況下會有16個RGB項。對應於索引0到索引15。
biBitCount=8 表示位圖最多有256種顏色。每個象素用8位表示,並用這8位作爲彩色表的表項來查找該象素的顏色。例如,如果位圖中的第一個字節爲0x1F,這個象素的顏色就在彩色表的第32表項中查找。此時,缺省情況下,調色板中會有256個RGB項,對應於索引0到索引255。
biBitCount=16 表示位圖最多有216種顏色。每個色素用16位(2個字節)表示。這種格式叫作高彩色,或叫增強型16位色,或64K色。它的情況比較複雜,當biCompression成員的值是BI_RGB時,它沒有調色板。16位中,最低的5位表示藍色分量,中間的5位表示綠色分量,高的5位表示紅色分量,一共佔用了15位,最高的一位保留,設爲0。這種格式也被稱作555 16位位圖。如果biCompression成員的值是BI_BITFIELDS,那麼情況就複雜了,首先是原來調色板的位置被三個DWORD變量佔據,稱爲紅、綠、藍掩碼。分別用於描述紅、綠、藍分量在16位中所佔的位置。在Windows 95(或98)中,系統可接受兩種格式的位域:555和565,在555格式下,紅、綠、藍的掩碼分別是:0x7C00、0x03E0、0x001F,而在565格式下,它們則分別爲:0xF800、0x07E0、0x001F。你在讀取一個像素之後,可以分別用掩碼“與”上像素值,從而提取出想要的顏色分量(當然還要再經過適當的左右移操作)。在NT系統中,則沒有格式限制,只不過要求掩碼之間不能有重疊。(注:這種格式的圖像使用起來是比較麻煩的,不過因爲它的顯示效果接近於真彩,而圖像數據又比真彩圖像小的多,所以,它更多的被用於遊戲軟件)。
biBitCount=24 表示位圖最多有224種顏色。這種位圖沒有調色板(bmiColors成員尺寸爲0),在位數組中,每3個字節代表一個象素,分別對應於顏色R、G、B。
biBitCount=32 表示位圖最多有232種顏色。這種位圖的結構與16位位圖結構非常類似,當biCompression成員的值是BI_RGB時,它也沒有調色板,32位中有24位用於存放RGB值,順序是:最高位—保留,紅8位、綠8位、藍8位。這種格式也被成爲888 32位圖。如果 biCompression成員的值是BI_BITFIELDS時,原來調色板的位置將被三個DWORD變量佔據,成爲紅、綠、藍掩碼,分別用於描述紅、綠、藍分量在32位中所佔的位置。在Windows 95(or 98)中,系統只接受888格式,也就是說三個掩碼的值將只能是:0xFF0000、0xFF00、0xFF。而在NT系統中,你只要注意使掩碼之間不產生重疊就行。(注:這種圖像格式比較規整,因爲它是DWORD對齊的,所以在內存中進行圖像處理時可進行彙編級的代碼優化(簡單))。
(3) ClrUsed
BITMAPINFOHEADER結構中的成員ClrUsed指定實際使用的顏色數目。如果ClrUsed設置成0,位圖使用的顏色數目就等於biBitCount成員中的數目。請注意,如果ClrUsed的值不是可用顏色的最大值或不是0,則在編程時應該注意調色板尺寸的計算,比如在4位位圖中,調色板的缺省尺寸應該是16*sizeof(RGBQUAD),但是,如果ClrUsed的值不是16或者不是0,那麼調色板的尺寸就應該是ClrUsed*sizeof(RGBQUAD)。
(4) 圖象數據壓縮
① BI_RLE8:每個象素爲8比特的RLE壓縮編碼,可使用編碼方式和絕對方式中的任何一種進行壓縮,這兩種方式可在同一幅圖中的任何地方使用。
編碼方式:由2個字節組成,第一個字節指定使用相同顏色的象素數目,第二個字節指定使用的顏色索引。此外,這個字節對中的第一個字節可設置爲0,聯合使用第二個字節的值表示:
|
第二個字節的值爲0:行的結束。
|
|
第二個字節的值爲1:圖象結束。
|
|
第二個字節的值爲2:其後的兩個字節表示下一個象素從當前開始的水平和垂直位置的偏移量。
|
絕對方式:第一個字節設置爲0,而第二個字節設置爲0x03~0xFF之間的一個值。在這種方式中,第二個字節表示跟在這個字節後面的字節數,每個字節包含單個象素的顏色索引。壓縮數據格式需要字邊界(word boundary)對齊。下面的例子是用16進製表示的8-位壓縮圖象數據:
03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01 02 78 00 00 09 1E 00 01
這些壓縮數據可解釋爲:
壓縮數據
|
擴展數據
|
03 04
|
04 04 04
|
05 06
|
06 06 06 06 06
|
00 03 45 56 67 00
|
45 56 67
|
02 78
|
78 78
|
00 02 05 01
|
從當前位置右移5個位置後向下移一行
|
02 78
|
78 78
|
00 00
|
行結束
|
09 1E
|
1E 1E 1E 1E 1E 1E 1E 1E 1E
|
00 01
|
RLE編碼圖象結束
|
② BI_RLE4:每個象素爲4比特的RLE壓縮編碼,同樣也可使用編碼方式和絕對方式中的任何一種進行壓縮,這兩種方式也可在同一幅圖中的任何地方使用。這兩種方式是:
編碼方式:由2個字節組成,第一個字節指定象素數目,第二個字節包含兩種顏色索引,一個在高4位,另一個在低4位。第一個象素使用高4位的顏色索引,第二個使用低4位的顏色索引,第3個使用高4位的顏色索引,依此類推。
絕對方式:這個字節對中的第一個字節設置爲0,第二個字節包含有顏色索引數,其後續字節包含有顏色索引,顏色索引存放在該字節的高、低4位中,一個顏色索引對應一個象素。此外,BI_RLE4也同樣聯合使用第二個字節中的值表示:
|
第二個字節的值爲0:行的結束。
|
|
第二個字節的值爲1:圖象結束。
|
|
第二個字節的值爲2:其後的兩個字節表示下一個象素從當前開始的水平和垂直位置的偏移量。
|
下面的例子是用16進制數表示的4-位壓縮圖象數據:
03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01 04 78 00 00 09 1E 00 01
這些壓縮數據可解釋爲 :
壓縮數據
|
擴展數據
|
03 04
|
0 4 0
|
05 06
|
0 6 0 6 0
|
00 06 45 56 67 00
|
4 5 5 6 6 7
|
04 78
|
7 8 7 8
|
00 02 05 01
|
從當前位置右移5個位置後向下移一行
|
04 78
|
7 8 7 8
|
00 00
|
行結束
|
09 1E
|
1 E 1 E 1 E 1 E 1
|
00 01
|
RLE圖象結束
|
彩色表:彩色表包含的元素與位圖所具有的顏色數相同。
typedef struct tagRGBQUAD { /* rgbq */
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
位圖數據
長度由圖像尺寸,象素位數,壓縮方式等共同決定.
由於存儲要求,圖像的列數必須爲4的整數倍
BMP文件的數據格式可以分爲兩大類:使用顏色表型和直接數據區型