1. BMP文件組成
BMP文件由文件頭、位圖信息頭、顏色信息和圖形數(shù)據(jù)四部分組成。文件頭主要包含文件的大小、文件類型、圖像數(shù)據(jù)偏離文件頭的長(zhǎng)度等信息;位圖信息頭包含圖象的尺寸信息、圖像用幾個(gè)比特?cái)?shù)值來(lái)表示一個(gè)像素、圖像是否壓縮、圖像所用的顏色數(shù)等信息。顏色信息包含圖像所用到的顏色表,顯示圖像時(shí)需用到這個(gè)顏色表來(lái)生成調(diào)色板,但如果圖像為真彩色,既圖像的每個(gè)像素用24個(gè)比特來(lái)表示,文件中就沒(méi)有這一塊信息,也就不需要操作調(diào)色板。文件中的數(shù)據(jù)塊表示圖像的相應(yīng)的像素值,需要注意的是:圖像的像素值在文件中的存放順序?yàn)閺淖蟮接遥瑥南碌缴希簿褪钦f(shuō),在BMP文件中首先存放的是圖像的最后一行像素,最后才存儲(chǔ)圖像的第一行像素,但對(duì)與同一行的像素,則是按照先左邊后右邊的的順序存儲(chǔ)的;另外一個(gè)需要讀者朋友關(guān)注的細(xì)節(jié)是:文件存儲(chǔ)圖像的每一行像素值時(shí),如果存儲(chǔ)該行像素值所占的字節(jié)數(shù)為4的倍數(shù),則正常存儲(chǔ),否則,需要在后端補(bǔ)0,湊足4的倍數(shù)。
2. BMP文件頭
BMP文件頭數(shù)據(jù)結(jié)構(gòu)含有BMP文件的類型、文件大小和位圖起始位置等信息。其結(jié)構(gòu)定義如下:
typedef struct tagBITMAPFILEHEADER
{
WORD bfType; // 位圖文件的類型,必須為“BM”
DWORD bfSize; // 位圖文件的大小,以字節(jié)為單位
WORD bfReserved1; // 位圖文件保留字,必須為0
WORD bfReserved2; // 位圖文件保留字,必須為0
DWORD bfOffBits; // 位圖數(shù)據(jù)的起始位置,以相對(duì)于位圖文件頭的偏移量表示,以字節(jié)為單位
} BITMAPFILEHEADER;該結(jié)構(gòu)占據(jù)14個(gè)字節(jié)。
3. 位圖信息頭
BMP位圖信息頭數(shù)據(jù)用于說(shuō)明位圖的尺寸等信息。其結(jié)構(gòu)如下:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本結(jié)構(gòu)所占用字節(jié)數(shù)
LONG biWidth; // 位圖的寬度,以像素為單位
LONG biHeight; // 位圖的高度,以像素為單位
WORD biPlanes; // 目標(biāo)設(shè)備的平面數(shù)不清,必須為1
WORD biBitCount// 每個(gè)像素所需的位數(shù),必須是1(雙色), 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位圖壓縮類型,必須是 0(不壓縮),1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一
DWORD biSizeImage; // 位圖的大小,以字節(jié)為單位
LONG biXPelsPerMeter; // 位圖水平分辨率,每米像素?cái)?shù)
LONG biYPelsPerMeter; // 位圖垂直分辨率,每米像素?cái)?shù)
DWORD biClrUsed;// 位圖實(shí)際使用的顏色表中的顏色數(shù)
DWORD biClrImportant;// 位圖顯示過(guò)程中重要的顏色數(shù)
} BITMAPINFOHEADER;該結(jié)構(gòu)占據(jù)40個(gè)字節(jié)。
注意:對(duì)于BMP文件格式,在處理單色圖像和真彩色圖像的時(shí)候,無(wú)論圖象數(shù)據(jù)多么龐大,都不對(duì)圖象數(shù)據(jù)進(jìn)行任何壓縮處理,一般情況下,如果位圖采用壓縮格式,那么16色圖像采用RLE4壓縮算法,256色圖像采用RLE8壓縮算法。
4. 顏色表
顏色表用于說(shuō)明位圖中的顏色,它有若干個(gè)表項(xiàng),每一個(gè)表項(xiàng)是一個(gè)RGBQUAD類型的結(jié)構(gòu),定義一種顏色。RGBQUAD結(jié)構(gòu)的定義如下:
typedef struct tagRGBQUAD {
BYTErgbBlue;// 藍(lán)色的亮度(值范圍為0-255)
BYTErgbGreen; // 綠色的亮度(值范圍為0-255)
BYTErgbRed; // 紅色的亮度(值范圍為0-255)
BYTErgbReserved;// 保留,必須為0
} RGBQUAD;
顏色表中RGBQUAD結(jié)構(gòu)數(shù)據(jù)的個(gè)數(shù)由BITMAPINFOHEADER 中的biBitCount項(xiàng)來(lái)確定,當(dāng)biBitCount=1,4,8時(shí),分別有2,16,256個(gè)顏色表項(xiàng),當(dāng)biBitCount=24時(shí),圖像為真彩色,圖像中每個(gè)像素的顏色用三個(gè)字節(jié)表示,分別對(duì)應(yīng)R、G、B值,圖像文件沒(méi)有顏色表項(xiàng)。位圖信息頭和顏色表組成位圖信息,BITMAPINFO結(jié)構(gòu)定義如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位圖信息頭
RGBQUAD bmiColors[1]; // 顏色表
} BITMAPINFO;
注意:RGBQUAD數(shù)據(jù)結(jié)構(gòu)中,增加了一個(gè)保留字段rgbReserved,它不代表任何顏色,必須取固定的值為“0”,同時(shí),RGBQUAD結(jié)構(gòu)中定義的顏色值中,紅色、綠色和藍(lán)色的排列順序與一般真彩色圖像文件的顏色數(shù)據(jù)排列順序恰好相反,既:若某個(gè)位圖中的一個(gè)像素點(diǎn)的顏色的描述為“00,00,ff,00”,則表示該點(diǎn)為紅色,而不是藍(lán)色。
5. 位圖數(shù)據(jù)
位圖數(shù)據(jù)記錄了位圖的每一個(gè)像素值或該對(duì)應(yīng)像素的顏色表的索引值,圖像記錄順序是在掃描行內(nèi)是從左到右,掃描行之間是從下到上。這種格式我們又稱為Bottom_Up位圖,當(dāng)然與之相對(duì)的還有Up_Down形式的位圖,它的記錄順序是從上到下的,對(duì)于這種形式的位圖,也不存在壓縮形式。位圖的一個(gè)像素值所占的字節(jié)數(shù):當(dāng)biBitCount=1時(shí),8個(gè)像素占1個(gè)字節(jié);當(dāng)biBitCount=4時(shí),2個(gè)像素占1個(gè)字節(jié);當(dāng)biBitCount=8時(shí),1個(gè)像素占1個(gè)字節(jié);當(dāng)biBitCount=24時(shí),1個(gè)像素占3個(gè)字節(jié),此時(shí)圖像為真彩色圖像。當(dāng)圖像不是為真彩色時(shí),圖像文件中包含顏色表,位圖的數(shù)據(jù)表示對(duì)應(yīng)像素點(diǎn)在顏色表中相應(yīng)的索引值,當(dāng)為真彩色時(shí),每一個(gè)像素用三個(gè)字節(jié)表示圖像相應(yīng)像素點(diǎn)彩色值,每個(gè)字節(jié)分別對(duì)應(yīng)R、G、B分量的值,這時(shí)候圖像文件中沒(méi)有顏色表。上面我已經(jīng)講過(guò)了,
Windows規(guī)定圖像文件中一個(gè)掃描行所占的字節(jié)數(shù)必須是4的倍數(shù)(即以字為單位),不足的以0填充,圖像文件中一個(gè)掃描行所占的字節(jié)數(shù)計(jì)算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;// 一個(gè)掃描行所占的字節(jié)數(shù)
或者
DataSizePerLine= (biWidth* biBitCount+31)/32 * 4;// 一個(gè)掃描行所占的字節(jié)數(shù)
(如果biBitCount == 8 或24)
DataSizePerLine= (biWidth* 3+3)/4*4;// 一個(gè)掃描行所占的字節(jié)數(shù)
或
DataSizePerLine= (biWidth*1+3)/4*4;// 一個(gè)掃描行所占的字節(jié)數(shù)
位圖數(shù)據(jù)的大小按下式計(jì)算(不壓縮情況下):
DataSize= DataSizePerLine* biHeight。
上述是BMP文件格式的說(shuō)明,搞清楚了以上的結(jié)構(gòu),就可以正確的操作圖像文件,對(duì)它進(jìn)行讀或?qū)懖僮髁恕?br>
轉(zhuǎn)自http://hi.baidu.com/kennlee/blog/item/52375eca63394743f31fe7d8.html