位元影像檔案頭的格式:
typedef struct{
int bfType;//bfType(2位元組),這裡恒定等於&H4D42,ASCII字元'BM'
long bfSize;//檔案大小,以4位元組為單位
int bfReserve1;//備用
int bfReserve2;//備用
long bfoffBits;//資料區在檔案中的位置位移量
}BITMAPFILEHEADER;//檔案頭結構體,14位元組
typedef struct{
long bitSize;//位元影像資訊頭大小
long biWidth;//圖象寬度,像素單位
long biHeight;//圖象高度,像素單位
int biPlanes;//位平面樹=1
int biBitCount;//單位像素的位元,表示bmp圖片的顏色位元,即24位元影像、32位元影像
long biCompression;//圖片的壓縮屬性,bmp圖片是不壓縮的,等於0
long biSizeImage;表示bmp圖片資料區的大小,當上一個屬性biCompression等於0時,這裡的值可以省略不填
long biXPlosPerMeter;//水平解析度,可省略
long biYPlosPerMeter;//垂直解析度,可省略
long biClrUsed;//表示使用了多少個色彩索引表,一般biBitCount屬性小於16才會用到,等於0時表示有2^biBitCount個色彩索引表
long biClrImportant;//表示有多少個重要的顏色,等於0時表示所有顏色都很重要
}BITMAPINFOHEADER;//位元影像資訊頭,40位元組
BMP檔案詳解(2)2007-03-21 12:26一個bmp檔案以BITMAPFILEHEADER結構體開始,BITMAPFILEHEADER的第1個屬性是bfType(2位元組),這裡恒定等於&H4D42。由於記憶體中的資料排列高位在左,低位在右,所以記憶體中從左往右看就顯示成(42 4D),所以在UltraEdit中頭兩個 位元組顯示為(42 4D)就是這樣形成的,以後的資料都是這個特點,不再作重複說明。
BITMAPFILEHEADER的第2個屬性是bfSize(4位元組),表示整個bmp檔案的大小,這裡等於&H000004F8=1272位元組。
BITMAPFILEHEADER的第3個、第4個屬性分別是bfReserved1、bfReserved2(各2位元組),這裡是2個保留屬性,都為0,這裡等於&H0000、&H0000。
BITMAPFILEHEADER的第5個屬性是bfOffBits(4位元組),表示DIB資料區在bmp檔案中的位置位移量,這裡等於&H00000076=118,表示資料區從檔案開始往後數的118位元組開始。
BITMAPFILEHEADER結構體這裡就講完了,大家會發現BITMAPFILEHEADER只佔了bmp檔案開始的14位元組長度,但需要 特別說明的是在vb中定義一個BITMAPFILEHEADER結構體變數,其長度佔了16個位元組,原因就是第1個屬性本來應該只分配2個位元組,但實際被 分配了4個位元組,多出來2個位元組,所以如果想儲存一張bmp圖片,寫入BITMAPFILEHEADER結構體時一定要注意這一點。
接下來是BITMAPINFO結構體部分。BITMAPINFO段由兩部分組成:BITMAPINFOHEADER結構體和RGBQUAD結構 體。其中RGBQUAD結構體表示圖片的顏色資訊,有些時候可以省略,一般的24位元影像片和32位元影像片都不帶RGBQUAD結構體,因為DIB資料區直接表 示的RGB值,一般4位元影像片和8位元影像片才帶有RGBQUAD結構體。(多少位的圖片就是用多少位來表示一個顏色資訊,例如4位元影像片表示用4個bit來表示 一個顏色資訊。)一個bmp檔案中有沒有RGBQUAD結構體,可以根據前面BITMAPFILEHEADER結構體的第5個屬性bfOffBits來判 斷,因為BITMAPINFOHEADER結構體長度為40bit,如果BITMAPINFOHEADER結構體結束後還未到DIB資料區的位移量,就說 明接下來的資料是RGBQUAD結構體部分。這裡講的C:/WINDOWS/Blue Lace 16.bmp是一個4bit圖片,所以它帶有 RGBQUAD結構體。
下面進入正題BITMAPINFOHEADER部分。
BITMAPINFOHEADER的第1個屬性是biSize(4位元組),表示BITMAPINFOHEADER結構體的長度,最常見的長度是40位元組,UltraEdit中可以看到緊接著的4個位元組等於&H00000028=40位元組。
BITMAPINFOHEADER的第2個屬性是biWidth(4位元組),表示bmp圖片的寬度,這裡等於&H00000030=48像素。
BITMAPINFOHEADER的第3個屬性是biHeight(4位元組),表示bmp圖片的高度,這裡等於&H00000030=48像素。
BITMAPINFOHEADER的第4個屬性是biPlanes(2位元組),表示bmp圖片的平面屬,顯然顯示器只有一個平面,所以恒等於1,這裡等於&H0001。
BITMAPINFOHEADER的第5個屬性是biBitCount(2位元組),表示bmp圖片的顏色位元,即24位元影像、32位元影像等等。這裡等於&H0004,表示該圖片為4位元影像。
BITMAPINFOHEADER的第6個屬性是biCompression(4位元組),表示圖片的壓縮屬性,bmp圖片是不壓縮的,等於0,所以這裡為&H00000000。
BITMAPINFOHEADER的第7個屬性是biSizeImage(4位元組),表示bmp圖片資料區的大小,當上一個熟悉biCompression等於0時,這裡的值可以省略不填,所以這裡等於&H00000000。
BITMAPINFOHEADER的第8個屬性是biXPelsPerMeter(4位元組),表示圖片X軸每米多少像素,可省略,這裡等於&H00000EC3=3779像素/米。
BITMAPINFOHEADER的第9個屬性是biYPelsPerMeter(4位元組),表示圖片Y軸每米多少像素,可省略,這裡等於&H00000EC3=3779像素/米。
BITMAPINFOHEADER的第10個屬性是biClrUsed(4位元組),表示使用了多少個色彩索引表,一般biBitCount屬性小於16才會用到,等於0時表示有2^biBitCount個色彩索引表,所以這裡仍等於&H00000000。
BITMAPINFOHEADER的第11個屬性是biClrImportant(4位元組),表示有多少個重要的顏色,等於0時表示所有顏色都很重要,所以這裡等於&H00000000。
至此BITMAPINFOHEADER結構體結束。
由於這個圖片到這裡還未到達DIB資料區的位移量,所以接下來的部分是RGBQUAD結構體。RGBQUAD結構體由4個位元組型資料群組成,所以一 個RGBQUAD結構體只佔用4位元組空間,從左至右每個位元組依次表示(藍色,綠色,紅色,未使用)。舉例的這個圖片我數了數總共有16個RGBQUAD結 構體,由於該圖片是4位元影像,2^4正好等於16,所以它把16種顏色全部都枚舉出來了,這些顏色就是一個色彩索引表。色彩索引表編號從0開始,總共16個 顏色,所以編號為0-15。從UltraEdit中可以看到按照順序,這16個RGBQUAD結構體依次為:
編號:(藍,綠,紅,空)
0號:(00,00,00,00)
1號:(00,00,80,00)
2號:(00,80,00,00)
3號:(00,80,80,00)
4號:(80,00,00,00)
5號:(80,00,80,00)
6號:(80,80,00,00)
7號:(80,80,80,00)
8號:(C0,C0,C0,00)
9號:(00,00,FF,00)
10號:(00,FF,00,00)
11號:(00,FF,FF,00)
12號:(FF,00,00,00)
13號:(FF,00,FF,00)
14號:(FF,FF,00,00)
15號:(FF,FF,FF,00)
為了更直觀的表示這些顏色,可以見後面的圖片。
到這裡,正好滿足DIB資料區的位移量,所以後面的位元組就是圖片內容了。這裡需要提醒的是所有的DIB資料掃描行是上下顛倒的,也就是說一幅圖片先繪製底部的像素,再繪製頂部的像素,所以這些DIB資料所表示的像素點就是從圖片的左下角開始,一直表示到圖片的右上方。
由於這裡的圖片是4位元影像片,也就是說4bit就表示一個像素,一個位元組有8個bit,所以一個位元組能表示2個像素。
從UltraEdit中可以看到,DIB資料區第一個位元組是&H44,16進位正好是將2進位數每4個一組書寫的,跟4bit圖片正好吻 合,所以&H44表示兩個像素,高位的4表示第一個像素,低位的4表示第二個像素。這裡的4不是表示RGB顏色,而是表示色彩索引號為4,由於索 引號從0開始編號的,所以4表示索引表中第5個顏色,從附圖中可以看到索引號為4的是藍色。這是第一位元組,表示的是圖片左下角開始2個像素,如果有 PhotoShop開啟這個圖片可以看到,左下角2個像素取出來的顏色RGB值正好等於索引表中第5個顏色的RGB值。後面的DIB資料以此類推。
至此一個bmp圖片就全部解析完了,根據這些資訊就可以完整的繪製一張bmp圖片來。
============================================
如果你還不明白,還有:
1. BMP檔案組成
BMP檔案由檔案頭、位元影像資訊頭、顏色資訊和圖形資料四部分組成。
2. BMP檔案頭
BMP檔案頭資料結構含有BMP檔案的類型、檔案大小和位元影像起始位置等資訊。
其結構定義如下:
typedef struct tagBITMAPFILEHEADER
{
WORDbfType; // 位元影像檔案的類型,必須為BM
DWORD bfSize; // 位元影像檔案的大小,以位元組為單位
WORDbfReserved1; // 位元影像檔案保留字,必須為0
WORDbfReserved2; // 位元影像檔案保留字,必須為0
DWORD bfOffBits; // 位元影像資料的起始位置,以相對於位元影像
// 檔案頭的位移量表示,以位元組為單位
} BITMAPFILEHEADER;
3. 位元影像資訊頭
BMP位元影像資訊頭資料用於說明位元影像的尺寸等資訊。
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本結構所佔用位元組數
LONGbiWidth; // 位元影像的寬度,以像素為單位
LONGbiHeight; // 位元影像的高度,以像素為單位
WORD biPlanes; // 目標裝置的層級,必須為1
WORD biBitCount// 每個像素所需的位元,必須是1(雙色),
// 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位元影像壓縮類型,必須是 0(不壓縮),
// 1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一
DWORD biSizeImage; // 位元影像的大小,以位元組為單位
LONGbiXPelsPerMeter; // 位元影像水平解析度,每米像素數
LONGbiYPelsPerMeter; // 位元影像垂直解析度,每米像素數
DWORD biClrUsed;// 位元影像實際使用的顏色表中的顏色數
DWORD biClrImportant;// 位元影像顯示過程中重要的顏色數
} BITMAPINFOHEADER;
4. 顏色表
顏色表用於說明位元影像中的顏色,它有若干個表項,每一個表項是一個RGBQUAD類型的結構,定義一種顏色。RGBQUAD結構的定義如下:
typedef struct tagRGBQUAD {
BYTErgbBlue;// 藍色的亮度(值範圍為0-255)
BYTErgbGreen; // 綠色的亮度(值範圍為0-255)
BYTErgbRed; // 紅色的亮度(值範圍為0-255)
BYTErgbReserved;// 保留,必須為0
} RGBQUAD;
顏色表中RGBQUAD結構資料的個數有biBitCount來確定:
當biBitCount=1,4,8時,分別有2,16,256個表項;
當biBitCount=24時,沒有顏色表項。
位元影像資訊頭和顏色表組成位元影像資訊,BITMAPINFO結構定義如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位元影像資訊頭
RGBQUAD bmiColors[1]; // 顏色表
} BITMAPINFO;
5. 位元影像資料
位元影像資料記錄了位元影像的每一個像素值,記錄順序是在掃描行內是從左至右,掃描行之間是從下到上。位元影像的一個像素值所佔的位元組數:
當biBitCount=1時,8個像素佔1個位元組;
當biBitCount=4時,2個像素佔1個位元組;
當biBitCount=8時,1個像素佔1個位元組;
當biBitCount=24時,1個像素佔3個位元組;
Windows規定一個掃描行所佔的位元組數必須是
4的倍數(即以long為單位),不足的以0填充,
一個掃描行所佔的位元組數計算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一個掃描行所佔的位元組數
DataSizePerLine= DataSizePerLine/4*4; // 位元組數必須是4的倍數
位元影像資料的大小(不壓縮情況下):
DataSize= DataSizePerLine* biHeight;
===============================================