BMP文件组成
BMP文件組成
BMP文件由文件頭、位圖信息頭、顏色信息和圖形數據四部分組成。 如圖:
| 位圖文件頭BITMAPFILEHEADER |
| 位圖信息頭BITMAPINFOHEADER |
| 調色板Palette |
| 實際的位圖數據ImageDate |
第一部分
為位圖文件頭BITMAPFILEHEADER,是一個結構,其定義如下:
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
bfType
指定文件類型,必須是0x424D,即字符串“BM”,也就是說所有.bmp文件的頭兩個字節都是“BM”。
bfSize
指定文件大小,包括這14個字節。
bfReserved1,bfReserved2
為保留字,不用考慮
bfOffBits
為從文件頭到實際的位圖數據的偏移字節數,即圖中前三個部分的長度之和。
第二部分
為位圖信息頭BITMAPINFOHEADER,也是一個結構,其定義如下:
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, *PBITMAPINFOHEADER;
biSize:指定結構體大小,按字節計算,不包括biClrUsed 成員提及的顏色表或掩碼的大小。參見備注。
biWidth: 位圖的寬度,按像素計算。
biHeight: 位圖的高度,按像素計算。
如果biHeight為正數,位圖為從下而上(bottom-up) DIB ,起點為左下角。
如果biHeight為負數,位圖為從上而下(top-down) DIB ,起點為左上角,
如果biHeight為負數,標識一個從上而下(top-down) DIB,biCompression必須為BI_RGB或BI_BITFIELDS。從上而下(top-down) DIB不能被壓縮。
biPlanes:指定目標設備的planes的數量。 必須設定為 1 。
biBitCount:指定每個像素的位數。
該成員決定位圖中定義每個像素的位數和最大顏色數量。 該成員必須為下面值中的一個:
|
值 |
描述 |
|
1 |
位圖為黑白色,bmiColors成員包含兩個入口。位圖數組中的每位代表一個像素。 |
|
2 |
位圖有4個可能的顏色值。 |
|
4 |
位圖有最大16位色,bmiColors成員最多包含16個入口。 顏色表按照4位索引呈現位圖中每個像素。例如,如果位圖中的第一個字節是Ox1F,該字節代表2個像素。第一個像素包含第二個表入口的顏色,第二個像素包含第16個表入口的顏色。 |
|
8 |
位圖最多有256中顏色,bmiColors成員包含最多256個入口。這種情況下,數組中的每個字節代表單獨一個像素。 |
|
16 |
位圖最多有2^16種顏色。 如果BITMAPINFOHEADER的biCompression成員值為BI_RGB,bmiColors為NULL。位圖數組中的每個字(WORD)代表單獨一個像素。紅、綠、藍的相對強度分別以5位呈現。藍色值為最低有效5位,接著5位是綠,然后是紅。最高有效位不被使用。bmiColors顏色表用來優化使用在基于調色板的設備上的顏色,而且必須包含BITMAPINFOHEADER的biClrUsed成員指定的入口數量。 |
|
24 |
位圖最多有2^24種顏色。bmiColors為NULL。 位圖數組中每個3字節三元組分別代表每個像素的藍、綠、紅色的相對強度。bmiColors顏色表用來優化使用在基于調色板的設備上的顏色,而且必須包含BITMAPINFOHEADER的biClrUsed成員指定的入口數量。 |
|
32 |
位圖最多有2^32種顏色。 如果BITMAPINFOHEADER的biCompression成員是BI_RGB,bmiColors為NULL。位圖數組中的每個雙字(DWORD)分別代表每個像素的藍、綠、紅色的相對強度。每個雙字的高字節不使用。bmiColors顏色表用來優化使用在基于調色板的設備上的顏色,而且必須包含BITMAPINFOHEADER的biClrUsed成員指定的入口數量。 如果BITMAPINFOHEADER的biCompression的值為BI_BITFIELDS,bmiColors成員包含3個雙字顏色掩碼來分別指定組成每個像素的紅、綠、藍色。 位圖數組中的每個雙字代表一個像素。 |
biCompression:為壓縮的bottom-up位圖指定壓縮類型,而top-down DIBs 不能被壓縮。該成員值可能為下表中的一個:
|
值 |
描述 |
|
BI_RGB |
未壓縮的格式 |
|
BI_BITFIELDS |
用來說明位圖沒有被壓縮并且顏色表由3個雙字顏色掩碼組成(3個雙字顏色掩碼來分別指定組成每個像素的紅、綠、藍值)。 當使用16bpp和32bpp位圖時該標志可用。 該值在Windows CE 2.0及其以后版本可用。 |
|
BI_ALPHABITFIELDS |
用來說明位圖沒有被壓縮并且顏色表由4個雙字顏色掩碼組成(4個雙字顏色掩碼來分別指定組成每個像素的紅、綠、藍和alpha值)。 當使用16bpp和32bpp位圖時該標志可用。 該值在Windows CE 4.0及其以后版本可用。 |
對于Windows CE 5.0 及其以后版本,可有使用上表的任意值與BI_SRCPREROTATE進行布爾OR運算來標明源DIB和目的DIB有相同的旋轉角度。
biSizeImage:指定圖像的大小,按字節計算。當為BI_RGB時,該值可以設置為0。
biXPelsPerMeter:為位圖指定目標設備水平分辨率,按每公尺像素數計算(in pixels per meter)。程序使用該值從資源組中選擇最符合當前設備特性的位圖。
biYPelsPerMeter:為位圖指定目標設備垂直分辨率按每公尺像素數計算(in pixels per meter)。
biClrUsed:指定實際在位圖中使用的顏色表中的顏色索引的數量。
如果該值為0,位圖為biCompression 指定的壓縮模式使用biBitCount 值對應的最大顏色數量。
如果biClrUsed 非0,并且biBitCount 小于16,biClrUsed 指定圖形引擎或設備驅動訪問的實際顏色數量。
如果biBitCount 大于等于16,biClrUsed 指定顏色表的數量,用來優化系統顏色調色板性能。
如果biBitCount 等于16或32,最佳顏色調色板緊跟在3個雙字掩碼之后開始(the optimal color palette starts immediately following the three DWORD masks.)。
如果位圖被封裝了(位圖數組緊接著BITMAPINFO頭,并被一個單獨指針引用),biClrUsed 必須要么為0,要么為顏色表的實際大小。
biClrImportant:顯示位圖時指的定顏色索引的數量。如果該值為0,要求使用所有顏色。
備注:
BITMAPINFO結構合并BITMAPINFOHEADER和一個顏色表來提供對一個DIB的尺寸大小和顏色的完全定義。程序應該使用存儲在biSize 中的信息來定位BITMAPINFO結構中的顏色表,如下,
pColor = ((LPSTR)pBitmapInfo + (WORD)(pBitmapInfo->bmiHeader.biSize));
對于Windows CE 1.0 和1.01版本,biBitCount 必須為1或2.
第三部分
為調色板Palette,當然,這里是對那些需要調色板的位圖文件而言的。有些位圖,如真彩色圖,前面已經講過,是不需要調色板的,BITMAPINFOHEADER后直接是位圖數據。
調色板實際上是一個數組,共有biClrUsed個元素(如果該值為零,則有2biBitCount個元素)。數組中每個元素的類型是一個RGBQUAD結構,占4個字節,其定義如下:
typedef struct tagRGBQUAD {
BYTE rgbBlue; //該顏色的藍色分量
BYTE rgbGreen; //該顏色的綠色分量
BYTE rgbRed; //該顏色的紅色分量
BYTE rgbReserved; //保留值
} RGBQUAD;
第四部分
位圖數據記錄了位圖的每一個像素值,記錄順序是在掃描行內是從左到右,掃描行之間是從下到上。對于用到調色板的位圖,圖象數據就是該象素顏在調色板中的索引值。對于真彩色圖,圖象數據就是實際的R、G、B值。下面針對2色、16色、256色位圖和真彩色位圖分別介紹。
對于2色位圖,用1位就可以表示該象素的顏色(一般0表示黑,1表示白),所以一個字節可以表示8個象素。
對于16色位圖,用4位可以表示一個象素的顏色,所以一個字節可以表示2個象素。
對于256色位圖,一個字節剛好可以表示1個象素。
對于真彩色圖,三個字節才能表示1個象素,哇,好費空間呀!沒辦法,誰叫你想讓圖的顏色顯得更亮麗呢,有得必有失嘛。
要注意兩點:
(1)每一行的字節數必須是4的整倍數,如果不是,則需要補齊。這在前面介紹biSizeImage時已經提到了。
(2)一般來說,.bMP文件的數據從下到上,從左到右的。也就是說,從文件中最先讀到的是圖象最下面一行的左邊第一個象素,然后是左邊第二個象素……接下來是倒數第二行左邊第一個象素,左邊第二個象素……依次類推 ,最后得到的是最上面一行的最右一個象素。
Windows GDI定義了將信息頭和顏色表組合在一起的數據結構BITMAPINFO
typedef struct tagBITMAPINFO {
BITMAPINFOHEADERbmiHeader;
RGBQUADbmiColors[1];
} BITMAPINFO;
成員:
bmiHeader: 位圖信息頭結構,該結構包含了位圖的尺寸和顏色格式。
bmiColors: 包含下面中的一種。
RGBQUAD 數組。數組元素填充顏色表。
16位無符號整形數組,該數組指定索引到當前已實現的邏輯調色板。
允許在使用DIB的函數中使用bmiColors 。當bmiColors 包含已實現的邏輯調色板的索引時,必須也要調用CreateDIBPatternBrushPt 和CreateDIBSection 。CreateDIBSection 的iUsage 成員必須被設置為DIB_PAL_COLORS 。
BITMAPINFOHEADER 結構的biBitCount 和 biClrUsed 成員的值決定數組的大小。
bmiColors 表中的顏色根據重要性排序。更多信息,參見備注。
如果bmiHeader.biCompression 被設置為BI_RGB ,可以設置bmiColors 數組大小為0.
備注:
設備獨立位圖由2部分組成:用于描述位圖的尺寸大小和顏色的BITMAPINFO 結構和定義位圖像素的字節數組。字節數組中的所有位封裝在一起,但每行掃描必須在行尾補0以確保行尾為LONG數據類型邊界(each scan line must be padded with zeroes to end on a LONG data-type
boundary.)。
如果位圖高度為正數,則位圖為從下到上(bottom-up)DIB,它的起點為左下角坐標。如果高度為負數,則位圖為從上到下(top-down) DIB,它的起點為左上角。
封裝位圖時,位圖字節數組緊跟在BITMAPINFO頭后面。封裝的位圖被一個單獨指針引用。
對于封裝的位圖,當使用DIB_PAL_COLORS模式時,BITMAPINFOHEADER 結構的ClrUsed 成員必須設置為偶數,因此,DIB位圖數組以DWORD邊界開始。
如果位圖被存儲至文件或傳送到其他應用程序,bmiColors 成員不應包含調色板索引。
除非程序獨占使用和控制位圖,否則位圖顏色表應該包含明確的RGB值。
安全提示: 一個常見的錯誤類型包括在內容中發現無效的格式描述。比如,一個BITMAPINFOHEADER 結構后跟著一個顏色表。
BITMAPINFO 結構被定義為一個BITMAPINFOHEADER 結構后跟著一個填充顏色表RGBQUAD 數組。RGBQUAD 數組大小由BITMAPINFOHEADER 中的biClrUsed值決定。
在拷貝顏色表到BITMAPINFO前一定要檢查為BITMAPINFO結構分配的緩沖大小,否則決不能那么做。
Windows GDI定義了將設備無關的位圖(DIB)和顏色表組合在一起的數據結構BITMAPCOREINFO。
typedef struct _BITMAPCOREINFO {
BITMAPCOREHEADER bmciHeader; //指定一個BITMAPCOREHEADER結構,它包含一個DIB的尺寸和顏色格式的信息
RGBTRIPLE bmciColors[1]; //RGBTRIPLE數組定義的位圖中的顏色
} BITMAPCOREINFO, *PBITMAPCOREINFO;
總結
- 上一篇: 因为犯罪被判三年刑,期间没办法还信用卡,
- 下一篇: 现在多少钱能和以80年代的万元户持平?