BMP文件格式
6.1.1 簡介
位圖文件(Bitmap-File,BMP)格式是Windows采用的圖像文件存儲格式,在Windows環(huán)境下運行的所有圖像處理軟件都支持這種格式。Windows 3.0以前的BMP位圖文件格式與顯示設備有關,因此把它稱為設備相關位圖(device-dependent bitmap,DDB)文件格式。Windows 3.0以后的BMP位圖文件格式與顯示設備無關,因此把這種BMP位圖文件格式稱為設備無關位圖(device-independent bitmap,DIB)格式,目的是為了讓Windows能夠在任何類型的顯示設備上顯示BMP位圖文件。BMP位圖文件默認的文件擴展名是BMP或者bmp。
6.1.2 文件結構
位圖文件可看成由4個部分組成:位圖文件頭(bitmap-file header)、位圖信息頭(bitmap-information header)、彩色表(color table)和定義位圖的字節(jié)陣列,它們的名稱和符號如表6-01所示。
表6-01 BMP圖像文件組成部分的名稱和符號
位圖文件的組成
|
結構名稱
|
符號
|
位圖文件頭(bitmap-file header)
|
BITMAPFILEHEADER
|
bmfh
|
位圖信息頭(bitmap-information header)
|
BITMAPINFOHEADER
|
bmih
|
彩色表(color table)
|
RGBQUAD
|
aColors[]
|
圖像數據陣列字節(jié)
|
BYTE
|
aBitmapBits[]
|
位圖文件結構可綜合在表6-02中。
表6-02 位圖文件結構內容摘要
|
偏移量
|
域的名稱
|
大小
|
內容
|
圖像文件
頭
|
0000h
|
標識符(Identifier)
|
2 bytes
|
兩字節(jié)的內容用來識別位圖的類型:
‘BM’ : Windows 3.1x, 95, NT, …
‘BA’ :OS/2 Bitmap Array
‘CI’ :OS/2 Color Icon
‘CP’ :OS/2 Color Pointer
‘IC’ : OS/2 Icon
‘PT’ :OS/2 Pointer
|
|
0002h
|
File Size
|
1 dword
|
用字節(jié)表示的整個文件的大小
|
|
0006h
|
Reserved
|
1 dword
|
保留,設置為0
|
|
000Ah
|
Bitmap Data Offset
|
1 dword
|
從文件開始到位圖數據開始之間的數據(bitmap data)之間的偏移量
|
|
000Eh
|
Bitmap Header Size
|
1 dword
|
位圖信息頭(Bitmap Info Header)的長度,用來描述位圖的顏色、壓縮方法等。下面的長度表示:
28h - Windows 3.1x, 95, NT, …
0Ch - OS/2 1.x
F0h - OS/2 2.x
|
|
0012h
|
Width
|
1 dword
|
位圖的寬度,以像素為單位
|
|
0016h
|
Height
|
1 dword
|
位圖的高度,以像素為單位
|
|
001Ah
|
Planes
|
1 word
|
位圖的位面數
|
圖像
信息
頭
|
001Ch
|
Bits Per Pixel
|
1 word
|
每個像素的位數
1 - Monochrome bitmap
4 - 16 color bitmap
8 - 256 color bitmap
16 - 16bit (high color) bitmap
24 - 24bit (true color) bitmap
32 - 32bit (true color) bitmap
|
|
001Eh
|
Compression
|
1 dword
|
壓縮說明:
0 - none (也使用BI_RGB表示)
1 - RLE 8-bit / pixel (也使用BI_RLE4表示)
2 - RLE 4-bit / pixel (也使用BI_RLE8表示)
3 - Bitfields (也使用BI_BITFIELDS表示)
|
|
0022h
|
Bitmap Data Size
|
1 dword
|
用字節(jié)數表示的位圖數據的大小。該數必須是4的倍數
|
|
0026h
|
HResolution
|
1 dword
|
用像素/米表示的水平分辨率
|
|
002Ah
|
VResolution
|
1 dword
|
用像素/米表示的垂直分辨率
|
|
002Eh
|
Colors
|
1 dword
|
位圖使用的顏色數。如8-位/像素表示為100h或者 256.
|
|
0032h
|
Important Colors
|
1 dword
|
指定重要的顏色數。當該域的值等于顏色數時,表示所有顏色都一樣重要
|
調色板數據
|
0036h
|
Palette
|
N * 4 byte
|
調色板規(guī)范。對于調色板中的每個表項,這4個字節(jié)用下述方法來描述RGB的值:
- 1字節(jié)用于藍色分量
- 1字節(jié)用于綠色分量
- 1字節(jié)用于紅色分量
- 1字節(jié)用于填充符(設置為0)
|
圖像數據
|
0436h
|
Bitmap Data
|
x bytes
|
該域的大小取決于壓縮方法,它包含所有的位圖數據字節(jié),這些數據實際就是彩色調色板的索引號
|
6.1.3 構件詳解
1. 位圖文件頭
位圖文件頭包含有關于文件類型、文件大小、存放位置等信息,在Windows 3.0以上版本的位圖文件中用BITMAPFILEHEADER結構來定義:
typedef struct tagBITMAPFILEHEADER { /* bmfh */
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
其中:
bfType
|
說明文件的類型.
|
bfSize
|
說明文件的大小,用字節(jié)為單位
|
bfReserved1
|
保留,設置為0
|
bfReserved2
|
保留,設置為0
|
bfOffBits
|
說明從BITMAPFILEHEADER結構開始到實際的圖像數據之間的字 節(jié)偏移量
|
2. 位圖信息頭
位圖信息用BITMAPINFO結構來定義,它由位圖信息頭(bitmap-information header)和彩色表(color table)組成,前者用BITMAPINFOHEADER結構定義,后者用RGBQUAD結構定義。BITMAPINFO結構具有如下形式:
typedef struct tagBITMAPINFO { /* bmi */
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
其中:
bmiHeader
|
說明BITMAPINFOHEADER結構
|
bmiColors
|
說明彩色表RGBQUAD結構的陣列
|
BITMAPINFOHEADER結構包含有位圖文件的大小、壓縮類型和顏色格式,其結構定義為:
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;
其中:
biSize
|
說明BITMAPINFOHEADER結構所需要的字節(jié)數
|
biWidth
|
說明圖像的寬度,以像素為單位
|
biHeight
|
說明圖像的高度,以像素為單位
|
biPlanes
|
為目標設備說明位面數,其值設置為1
|
biBitCount
|
說明位數/像素,其值為1、2、4或者24
|
biCompression
|
- 說明圖像數據壓縮的類型。其值可以是下述值之一:
BI_RGB:沒有壓縮;
- BI_RLE8:每個像素8位的RLE壓縮編碼,壓縮格式由2字節(jié)組成(重復像素計數和顏色索引);
- BI_RLE4:每個像素4位的RLE壓縮編碼,壓縮格式由2字節(jié)組成
|
biSizeImage
|
說明圖像的大小,以字節(jié)為單位。當用BI_RGB格式時,可設置為0
|
biXPelsPerMeter
|
說明水平分辨率,用像素/米表示
|
biYPelsPerMeter
|
說明垂直分辨率,用像素/米表示
|
biClrUsed
|
說明位圖實際使用的彩色表中的顏色索引數
|
biClrImportant
|
說明對圖像顯示有重要影響的顏色索引的數目,如果是0,表示都重要。
|
現就BITMAPINFOHEADER結構作如下說明:
(1) 彩色表的定位
應用程序可使用存儲在biSize成員中的信息來查找在BITMAPINFO結構中的彩色表,如下所示:
pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))
(2) biBitCount
biBitCount=1 表示位圖最多有兩種顏色,黑色和白色。圖像數據陣列中的每一位表示一個像素。
biBitCount=4 表示位圖最多有16種顏色。每個像素用4位表示,并用這4位作為彩色表的表項來查找該像素的顏色。例如,如果位圖中的第一個字節(jié)為0x1F,它表示有兩個像素,第一像素的顏色就在彩色表的第2表項中查找,而第二個像素的顏色就在彩色表的第16表項中查找。
biBitCount=8 表示位圖最多有256種顏色。每個像素用8位表示,并用這8位作為彩色表的表項來查找該像素的顏色。例如,如果位圖中的第一個字節(jié)為0x1F,這個像素的顏色就在彩色表的第32表項中查找。
biBitCount=24 表示位圖最多有224=16 777 216種顏色。bmiColors (或者bmciColors)成員就為NULL。每3個字節(jié)代表一個像素,其顏色有R、G、B字節(jié)的相對強度決定。
(3) ClrUsed
BITMAPINFOHEADER結構中的成員ClrUsed指定實際使用的顏色數目。如果ClrUsed設置成0,位圖使用的顏色數目就等于biBitCount成員中的數目。
(4) 圖像數據壓縮
① BI_RLE8:每個像素為8位的RLE壓縮編碼,可使用編碼方式和絕對方式中的任何一種進行壓縮,這兩種方式可在同一幅圖中的任何地方使用。
編碼方式:由2個字節(jié)組成,第一個字節(jié)指定使用相同顏色的像素數目,第二個字節(jié)指定使用的顏色索引。此外,這個字節(jié)對中的第一個字節(jié)可設置為0,聯(lián)合使用第二個字節(jié)的值表示:
- 第二個字節(jié)的值為0:行的結束。
- 第二個字節(jié)的值為1:圖像結束。
- 第二個字節(jié)的值為2:其后的兩個字節(jié)表示下一個像素從當前開始的水平和垂直位置的偏移量。
絕對方式:第一個字節(jié)設置為0,而第二個字節(jié)設置為0x03~0xFF之間的一個值。在這種方式中,第二個字節(jié)表示跟在這個字節(jié)后面的字節(jié)數,每個字節(jié)包含單個像素的顏色索引。壓縮數據格式需要字邊界(word boundary)對齊。
[例6.1] 用十六進制表示的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個字節(jié)組成,第一個字節(jié)指定像素數目,第二個字節(jié)包含兩種顏色索引,一個在高4位,另一個在低4位。第一個像素使用高4位的顏色索引,第二個使用低4位的顏色索引,第3個使用高4位的顏色索引,依此類推。
絕對方式:這個字節(jié)對中的第一個字節(jié)設置為0,第二個字節(jié)包含有顏色索引數,其后續(xù)字節(jié)包含有顏色索引,顏色索引存放在該字節(jié)的高、低4位中,一個顏色索引對應一個像素。此外,BI_RLE4也同樣聯(lián)合使用第二個字節(jié)中的值表示:
- 第二個字節(jié)的值為0:行的結束。
- 第二個字節(jié)的值為1:圖像結束。
- 第二個字節(jié)的值為2:其后的兩個字節(jié)表示下一個像素從當前開始的水平和垂直位置的偏移量。
[例6.2] 用十六進制數表示的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圖像結束
|
3. 彩色表
彩色表包含的元素與位圖所具有的顏色數相同,像素的顏色用RGBQUAD結構來定義。對于24-位真彩色圖像就不使用彩色表,因為位圖中的RGB值就代表了每個像素的顏色。彩色表中的顏色按顏色的重要性排序,這可以輔助顯示驅動程序為不能顯示足夠多顏色數的顯示設備顯示彩色圖像。RGBQUAD結構描述由R、G、B相對強度組成的顏色,定義如下:
typedef struct tagRGBQUAD { /* rgbq */
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
其中:
rgbBlue
|
指定藍色強度
|
rgbGreen
|
指定綠色強度
|
rgbRed
|
指定紅色強度
|
rgbReserved
|
保留,設置為0
|
4. 位圖數據
緊跟在彩色表之后的是圖像數據字節(jié)陣列。圖像的每一掃描行由表示圖像像素的連續(xù)的字節(jié)組成,每一行的字節(jié)數取決于圖像的顏色數目和用像素表示的圖像寬度。掃描行是由底向上存儲的,這就是說,陣列中的第一個字節(jié)表示位圖左下角的像素,而最后一個字節(jié)表示位圖右上角的像素。
|