http://blog.chinaunix.net/u/11557/showart.php?id=86169(出處)
位圖是最常用的windows圖形格式,通過(guò)windows API函數(shù)可以直接讀取并繪制,不過(guò),有時(shí)我們還是需要自己控制,那么,就讓我們看看他的格式吧!
位圖文件結(jié)構(gòu)表
位圖文件
位圖文件頭
14 字節(jié)
位圖信息頭
40 字節(jié)
彩色表(調(diào)色板)
4N 字節(jié)
位圖數(shù)據(jù)
x 字節(jié)
構(gòu)件詳解:
位圖文件頭
位圖文件頭包含文件類(lèi)型、文件大小、存放位置等信息。結(jié)構(gòu)定義如下:
typedef struct tagBITMAPFILEHEADER
{
UNIT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
}BITMAPFILEHEADER;
其中:
bfType 說(shuō)明文件類(lèi)型,在windows系統(tǒng)中為BM。
bfSize 說(shuō)明文件大小。
bfReserved1 bfReserved2 保留,設(shè)置為0。
bfOffBits 說(shuō)明實(shí)際圖形數(shù)據(jù)的偏移量。
位圖信息頭
位圖信息頭包含位圖的大小、壓縮類(lèi)型、和顏色格式,結(jié)構(gòu)定義如下:
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMerer;
LONG biYPelsPerMerer;
DWORD biClrUsed;
DWORD biClrImportant;
}BITMAPINFOHEADER;
其中:
biSize 說(shuō)明BITMAPINFOHEADER結(jié)構(gòu)所需字節(jié)數(shù),在windows系統(tǒng)中為28h
biWidth 說(shuō)明圖像寬度
biHeight 說(shuō)明圖像高度
biPlanes 為目標(biāo)設(shè)備說(shuō)明位面數(shù),其值設(shè)為1
biBitCount每個(gè)像素的位數(shù),單色位圖為1,256色為8,24bit為24。
biCompression壓縮說(shuō)明,BI_RGB:無(wú)壓縮,BI_RLE8:8位RLE壓縮,BI_RLE4:4位RLE壓縮
biSizeImage說(shuō)明圖像大小,如無(wú)壓縮,可設(shè)為0
biXPelsPerMeter水平分辨率
biYPelsPerMeter垂直分辨率
biClrUsed 位圖使用的顏色數(shù)
biImportant重要顏色數(shù)目
彩色表
彩色表包含的元素與位圖所具有的顏色數(shù)目相同,像素顏色用結(jié)構(gòu)RGBQUAD來(lái)表示:
typedef struct tagRGBQUAD
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
}RGBQUAD;
其中:
rgbBlue 指定藍(lán)色強(qiáng)度
rgbGreen 指定綠色強(qiáng)度
rgbRed 指定紅色強(qiáng)度
rgbReserved保留,設(shè)為0
位圖數(shù)據(jù)
緊跟在彩色表后的是圖像數(shù)據(jù)震裂,圖像每一掃描行有連續(xù)的字節(jié)組成,掃描行由底向上存儲(chǔ),陣列中第一字節(jié)為左下角像素,最后一字節(jié)為右上角像素。
要想處理圖像文件就必須知道這些圖像文件的構(gòu)成方式。在常用的圖像格式中,以24位真彩色的BMP位圖格式比較常用,而且構(gòu)成比較簡(jiǎn)單,所以我們就以它作為講解的對(duì)象。
首先我們找一幅 24 位真彩色的位圖用 16 進(jìn)制編輯器將其打開(kāi),查看方式切換到以 HEX 方式查看的話,你們就可以看到類(lèi)似下面這樣的數(shù)據(jù)了。這其實(shí)就是 BMP 文件中的圖像數(shù)據(jù)。這些數(shù)據(jù)就代表著我們平??吹降膱D像。
00000
42
4D
96
61
02
00
00
00
00
00
36
00
00
00
28
00
00010
00
00
04
01
00
00
C8
00
00
00
01
00
18
00
00
00
00020
00
00
60
61
02
00
00
00
00
00
00
00
00
00
00
00
00030
00
00
00
00
00
00
0A
0A
0A
0B
0B
0B
10
10
10
17
00040
17
17
1C
1C
1C
1B
1B
1B
14
14
14
0D
0D
0D
0F
0F
00050
0F
0E
0E
0E
0E
0E
0E
0E
0E
0E
10
10
10
13
13
13
00060
16
16
16
18
18
18
15
15
15
19
19
19
17
17
17
0F
00070
0F
0F
0B
0B
0B
0E
0E
0E
11
11
11
10
10
10
0B
0B
00080
0B
14
14
14
17
17
17
11
11
11
0F
0F
0F
14
14
14
00090
14
14
14
0D
0F
0F
05
0A
0D
09
10
13
10
15
18
0F
24 位真彩色的 BMP 圖文件是由三個(gè)部分組成的:位圖文件頭、位圖信息頭、位圖陣列三個(gè)部分組成的。
1.1 位圖文件頭
位圖文件頭就是用來(lái)標(biāo)志這個(gè)位圖文件一些信息比如:大小、類(lèi)型等等。共有 14 個(gè)字節(jié)的信息。下面我們就分別對(duì)這 14 個(gè)字節(jié)的信息分別說(shuō)明一下它們所代表的意義。
42 4D 為位圖的標(biāo)志。如果轉(zhuǎn)換成 ASCII 碼的話就是 BM。
96 61 02 00 這個(gè)雙字信息代表著位圖文件的總字切數(shù),如果把它轉(zhuǎn)換面十進(jìn)制的話就是( 00026196 ) H= ( 156054 ) D ,也就是這位圖文件的大小是 156054 個(gè)字節(jié)。
00 00 00 00 為保留字。
36 00 00 00 表示位圖陣列的起始位置,( 00000036 ) H= ( 54 ) D ,也就是從第 54 個(gè)字節(jié)起就是這幅圖的位圖陣列了。
1.2 位圖信息頭
位圖信息頭記錄著一些關(guān)于這幅圖的一些基本信息,比如:高度、寬度、分辨率等信息。共占 40 個(gè)字節(jié)。
28 00 00 00 表示著位圖信息頭的長(zhǎng)度,( 00000028 ) H= ( 40 ) D ,即位圖信息頭的長(zhǎng)度占 40 個(gè)字節(jié)。
04 01 00 00 表示位圖的寬度,( 00000104 ) H= ( 260 ) D 表示位圖的寬度為 260 個(gè)像素。
C8 00 00 00 表示位圖的高度,( 000000C8 ) H= ( 200 ) D 表示位圖的高度為 200 個(gè)像素。
01 00 表示位圖設(shè)備級(jí)別。
18 00 位圖的色彩級(jí)別,( 0018 ) H= ( 24 ) D ,即表示 24 位真彩色。
00 00 00 00 表示壓縮類(lèi)型,零表示不壓縮。
00 00 00 00 位圖陣列表字節(jié)數(shù)。
00 00 00 00 表示水平分辨率。
00 00 00 00 表示垂直分辨率。
00 00 00 00 表示位圖實(shí)際使用的顏色表中的顏色變址。
00 00 00 00 表示位圖顯示過(guò)程中被認(rèn)為重要顏色變址數(shù)。
1.3 位圖陣列
這部分就是這幅圖像的主體部分了。其實(shí)每幅圖像都是由一個(gè)一個(gè)的點(diǎn)組成的。在位圖陣列里就存放著每一個(gè)點(diǎn)的顏色信息。每個(gè)像素點(diǎn)是由 3 個(gè)字節(jié)的數(shù)據(jù)組成的。也就是我們常用到的 RGB 色彩空間每種顏色占一個(gè)字節(jié)。每個(gè)點(diǎn)的顏色都是由藍(lán)色、綠色、紅色這個(gè)順序存儲(chǔ)的。點(diǎn)的存儲(chǔ)順序是從左到右從下到上,也就是說(shuō)第一個(gè)點(diǎn)是這幅圖的第一列的最后一個(gè)點(diǎn)(左下角的那個(gè)點(diǎn)),之后是它上面的那個(gè)點(diǎn),就這樣由下至上直到第一列的第一個(gè)點(diǎn)(左上角的那個(gè)點(diǎn)),然后是第二列也是從下至上的順序。直到寫(xiě)完所有的點(diǎn)。
2. RGB 和 YCrCb 的轉(zhuǎn)換
“顏色空間”的問(wèn)題我們?cè)诤竺嬷v解的一個(gè)效果中要用到所以我們?cè)谶@里簡(jiǎn)單的講解一下。
2.1 RGB
對(duì)一種顏色進(jìn)行編碼的方法統(tǒng)稱(chēng)為“顏色空間”或“色域”。用最簡(jiǎn)單的話說(shuō),世界上任何一種顏色的“顏色空間”都可定義成一個(gè)固定的數(shù)字或變量。 RGB (紅、綠、藍(lán))只是眾多顏色空間的一種。采用這種編碼方法,每種顏色都可用三個(gè)變量來(lái)表示:紅色、綠色以及藍(lán)色的強(qiáng)度。記錄及顯示彩色圖像時(shí), RGB 是最常見(jiàn)的一種方案。
2.2 YUV(變稱(chēng) YCrCb)
YUV (亦稱(chēng) YCrCb )是被歐洲電視系統(tǒng)所采用的一種顏色編碼方法(屬于 PAL)。 YUV 主要用于優(yōu)化彩色視頻信號(hào)的傳輸。其中“ Y ”表示明亮度( Luminance 或 Luma ),也就是灰階值;而“ U ”和“ V ”表示的則是色度( Chrominance 或 Chroma ),作用是描述影像色彩及飽和度,用于指定像素的顏色。“亮度”是通過(guò) RGB 輸入信號(hào)來(lái)創(chuàng)建的,方法是將 RGB 信號(hào)的特定部分疊加到一起。“色度”則定義了顏色的兩個(gè)方面—色調(diào)與飽和度,分別用 Cr 和 CB 來(lái)表示。其中, Cr 反映了 RGB 輸入信號(hào)紅色部分與 RGB 信號(hào)亮度值之間的差異。而 CB 反映的是 RGB 輸入信號(hào)藍(lán)色部分與 RGB 信號(hào)亮度值之同的差異。
2.3 RGB 與 YcrCb 之間的轉(zhuǎn)換
在上面我們已經(jīng)給大家簡(jiǎn)單的描述了一下 RGB 和 YcrCb ,下面我們就要講解一下它們的轉(zhuǎn)換過(guò)程。
YcrCb 轉(zhuǎn)換到 RGB,注意到 0.299 + 0.587 + 0.114=1.0 三原色的系數(shù)之所以不同是因?yàn)槿说难劬?duì)不同波長(zhǎng)的顏色有著不同的敏感度:
Y = 0.299*R + 0.587*G + 0.114*B
Cb =-0.1687*R - 0.3313*G + 0.5*B
Cr =0.5*R - 0.4187*G - 0.0813*B
RGB 轉(zhuǎn)換回 YcrCb :
R = Y+1.402*Cr
G = Y-0.34414*Cb-0.71414*Cr
B = Y+1.772*Cb