ubuntu下codeblocks起步(九)-上

ubuntu下codeblocks起步(九)-bmp位圖


BMP文件格式分析

要對bmp位圖文件編程首先要知道bmp文件的文件格式。在程序設計的開始首先轉載了一篇關於bmp文件格式的文章。文章對bmp文件的文件格式剖析的很詳盡,值得一看!

///////////////////////////////////////////////////////////////////

本文爲全文轉貼,不知道最初作者是誰,我的轉貼來源是:BAIDU搜索得到的http://www.hf110.com/Article/jswz/bcjs/ozh/200504/888.html。僅供個人參考。
BMP文件格式分析
作者:YZ 文章來源:ISee 點擊數: 1311 更新時間:2005-4-8

本來不想寫這篇東西,因爲介紹BMP文件結構的資料太多了,都有些濫了。但剛寫完BMP的讀寫模塊,又不想不留下點什麼,所以就寫了,全當是學習筆記吧。自己以後查資料時也方便一些,也許對某些初哥還會有點用^_^
注:本文參考了林福宗老師的有關BMP文件格式的文章,在此聲明。
簡介
BMP (Bitmap-File)圖形文件是Windows採用的圖形文件格式,在Windows環境下運行的所有圖象處理軟件都支持BMP圖象文件格式。 Windows系統內部各圖像繪製操作都是以BMP爲基礎的。Windows 3.0以前的BMP圖文件格式與顯示設備有關,因此把這種BMP圖象文件格式稱爲設備相關位圖DDB(device-dependent bitmap)文件格式。Windows 3.0以後的BMP圖象文件與顯示設備無關,因此把這種BMP圖象文件格式稱爲設備無關位圖DIB(device-independent bitmap)格式(注:Windows 3.0以後,在系統中仍然存在DDB位圖,象BitBlt()這種函數就是基於DDB位圖的,只不過如果你想將圖像以BMP格式保存到磁盤文件中時,微軟 極力推薦你以DIB格式保存),目的是爲了讓Windows能夠在任何類型的顯示設備上顯示所存儲的圖象。BMP位圖文件默認的文件擴展名是BMP或者 bmp(有時它也會以.DIB或.RLE作擴展名)。
6.1.2 文件結構
位圖文件可看成由4個部分組成:位圖文件頭(bitmap-file header)、位圖信息頭(bitmap-information header)、彩色表(color table)和定義位圖的字節陣列,它具有如下所示的形式。
位圖文件的組成 結構名稱 符號
位圖文件頭(bitmap-file header) BITMAPFILEHEADER bmfh
位圖信息頭(bitmap-information header) BITMAPINFOHEADER bmih
彩色表(color table) RGBQUAD aColors[]
圖象數據陣列字節 BYTE aBitmapBits[]

圖象文件 頭
0000h 文件標識 2 bytes 兩字節的內容用來識別位圖的類型:
‘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
注:因爲OS/2系統並沒有被普及開,所以在編程時,你只需判斷第一個標識“BM”就行。
0002h File Size 1 dword 用字節表示的整個文件的大小
  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
注: 在Windows95、98、2000等操作系統中,位圖信息頭的長度並不一定是28h,因爲微軟已經制定出了新的BMP文件格式,其中的信息頭結構變化 比較大,長度加長。所以最好不要直接使用常數28h,而是應該從具體的文件中讀取這個值。這樣才能確保程序的兼容性。
0012h Width 1 dword 位圖的寬度,以象素爲單位
  0016h Height 1 dword 位圖的高度,以象素爲單位
  001Ah Planes 1 word 位圖的位面數(注:該值將總是1)

001Ch Bits Per Pixel 1 word 每個象素的位數
1 - 單色位圖(實際上可有兩種顏色,缺省情況下是黑色和白色。你可以自己定義這兩種顏色) 4 - 16 色位圖 8 - 256 色位圖 16 - 16bit 高彩色位圖 24 - 24bit 真彩色位圖 32 - 32bit 增強型真彩色位圖
  001Eh Compression 1 dword 壓縮說明:
0 - 不壓縮 (使用BI_RGB表示) 1 - RLE 8-使用8位RLE壓縮方式(用BI_RLE8表示) 2 - RLE 4-使用4位RLE壓縮方式(用BI_RLE4表示) 3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)

  0022h Bitmap Data Size 1 dword 用字節數表示的位圖數據的大小。該數必須是4的倍數
  0026h HResolution 1 dword 用象素/米表示的水平分辨率
  002Ah VResolution 1 dword 用象素/米表示的垂直分辨率
  002Eh Colors 1 dword 位圖使用的顏色數。如8-比特/象素表示爲100h或者 256.
  0032h Important Colors 1 dword 指定重要的顏色數。當該域的值等於顏色數時(或者等於0時),表示所有顏色都一樣重要
調色板數據 根據BMP版本的不同而不同 Palette N * 4 byte 調色板規範。對於調色板中的每個表項,這4個字節用下述方法來描述RGB的值: 1字節用於藍色分量
1字節用於綠色分量 1字節用於紅色分量 1字節用於填充符(設置爲0)

圖 象數據 根據BMP版本及調色板尺寸的不同而不同 Bitmap Data xxx bytes 該域的大小取決於壓縮方法及圖像的尺寸和圖像的位深度,它包含所有的位圖數據字節,這些數據可能是彩色調色板的索引號,也可能是實際的RGB值,這將根據 圖像信息頭中的位深度值來決定。

構件詳解

1. 位圖文件頭

位圖文件頭包含有關於文件類型、文件大小、存放位置等信息,在Windows 3.0以上版本的位圖文件中用BITMAPFILEHEADER結構來定義:
typedef struct tagBITMAPFILEHEADER { /* bmfh */
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;

其中:
bfType
說明文件的類型.(該值必需是0x4D42,也就是字符'BM'。我們不需要判斷OS/2的位圖標識,這麼做現在來看似乎已經沒有什麼意義了,而且如果要支持OS/2的位圖,程序將變得很繁瑣。所以,在此只建議你檢察'BM'標識)

bfSize
說明文件的大小,用字節爲單位

bfReserved1
保留,必須設置爲0

bfReserved2
保留,必須設置爲0

bfOffBits
說明從文件頭開始到實際的圖象數據之間的字節的偏移量。這個參數是非常有用的,因爲位圖信息頭和調色板的長度會根據不同情況而變化,所以你可以用這個偏移值迅速的從文件中讀取到位數據。

2. 位圖信息頭

位 圖信息用BITMAPINFO結構來定義,它由位圖信息頭(bitmap-information header)和彩色表(color table)組成,前者用BITMAPINFOHEADER結構定義,後者用RGBQUAD結構定義。BITMAPINFO結構具有如下形式:

typedef struct tagBITMAPINFO { /* bmi */
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;

其中:
bmiHeader
說明BITMAPINFOHEADER結構,其中包含了有關位圖的尺寸及位格式等信息

bmiColors
說明彩色表RGBQUAD結構的陣列,其中包含索引圖像的真實RGB值。


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結構所需要的字數。注:這個值並不一定是BITMAPINFOHEADER結構的尺寸,它也可能是sizeof (BITMAPV4HEADER)的值,或是sizeof(BITMAPV5HEADER)的值。這要根據該位圖文件的格式版本來決定,不過,就現在的情 況來看,絕大多數的BMP圖像都是BITMAPINFOHEADER結構的(可能是後兩者太新的緣故吧:-)。

biWidth
說明圖象的寬度,以象素爲單位

biHeight
說明圖象的高度,以象素爲單位。注:這個值除了用於描述圖像的高度之外,它還有另一個用處,就是指明該圖像是倒向的位圖,還是正向的位圖。如果該值是一個 正數,說明圖像是倒向的,如果該值是一個負數,則說明圖像是正向的。大多數的BMP文件都是倒向的位圖,也就是時,高度值是一個正數。(注:當高度值是一 個負數時(正向圖像),圖像將不能被壓縮(也就是說biCompression成員將不能是BI_RLE8或BI_RLE4)。

biPlanes
爲目標設備說明位面數,其值將總是被設爲1

biBitCount
說明比特數/象素,其值爲1、4、8、16、24、或32

biCompression
說明圖象數據壓縮的類型。其值可以是下述值之一:
BI_RGB:沒有壓縮;

BI_RLE8:每個象素8比特的RLE壓縮編碼,壓縮格式由2字節組成(重複象素計數和顏色索引);

BI_RLE4:每個象素4比特的RLE壓縮編碼,壓縮格式由2字節組成

BI_BITFIELDS:每個象素的比特由指定的掩碼決定。

biSizeImage
說明圖象的大小,以字節爲單位。當用BI_RGB格式時,可設置爲0
biXPelsPerMeter
說明水平分辨率,用象素/米表示
biYPelsPerMeter
說明垂直分辨率,用象素/米表示
biClrUsed
說明位圖實際使用的彩色表中的顏色索引數(設爲0的話,則說明使用所有調色板項)
biClrImportant
說明對圖象顯示有重要影響的顏色索引的數目,如果是0,表示都重要。

現就BITMAPINFOHEADER結構作如下說明:

(1) 彩色表的定位

應用程序可使用存儲在biSize成員中的信息來查找在BITMAPINFO結構中的彩色表,如下所示:

pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo->bmiHeader.biSize))

(2) biBitCount

biBitCount=1 表示位圖最多有兩種顏色,缺省情況下是黑色和白色,你也可以自己定義這兩種顏色。圖像信息頭裝調色板中將有兩個調色板項,稱爲索引0和索引1。圖象數據陣 列中的每一位表示一個象素。如果一個位是0,顯示時就使用索引0的RGB值,如果位是1,則使用索引1的RGB值。

biBitCount=4 表示位圖最多有16種顏色。每個象素用4位表示,並用這4位作爲彩色表的表項來查找該象素的顏色。例如,如果位圖中的第一個字節爲0x1F,它表示有兩個 象素,第一象素的顏色就在彩色表的第2表項中查找,而第二個象素的顏色就在彩色表的第16表項中查找。此時,調色板中缺省情況下會有16個RGB項。對應 於索引0到索引15。

biBitCount=8 表示位圖最多有256種顏色。每個象素用8位表示,並用這8位作爲彩色表的表項來查找該象素的顏色。例如,如果位圖中的第一個字節爲0x1F,這個象素的 顏色就在彩色表的第32表項中查找。此時,缺省情況下,調色板中會有256個RGB項,對應於索引0到索引255。

biBitCount=16 表示位圖最多有216種顏色。每個色素用16位(2個字節)表示。這種格式叫作高彩色,或叫增強型16位色,或64K色。它的情況比較複雜,當 biCompression成員的值是BI_RGB時,它沒有調色板。16位中,最低的5位表示藍色分量,中間的5位表示綠色分量,高的5位表示紅色分 量,一共佔用了15位,最高的一位保留,設爲0。這種格式也被稱作555 16位位圖。如果biCompression成員的值是BI_BITFIELDS,那麼情況就複雜了,首先是原來調色板的位置被三個DWORD變量佔據, 稱爲紅、綠、藍掩碼。分別用於描述紅、綠、藍分量在16位中所佔的位置。在Windows 95(或98)中,系統可接受兩種格式的位域:555和565,在555格式下,紅、綠、藍的掩碼分別是:0x7C00、0x03E0、0x001F,而 在565格式下,它們則分別爲:0xF800、0x07E0、0x001F。你在讀取一個像素之後,可以分別用掩碼“與”上像素值,從而提取出想要的顏色 分量(當然還要再經過適當的左右移操作)。在NT系統中,則沒有格式限制,只不過要求掩碼之間不能有重疊。(注:這種格式的圖像使用起來是比較麻煩的,不 過因爲它的顯示效果接近於真彩,而圖像數據又比真彩圖像小的多,所以,它更多的被用於遊戲軟件)。

biBitCount=24 表示位圖最多有224種顏色。這種位圖沒有調色板(bmiColors成員尺寸爲0),在位數組中,每3個字節代表一個象素,分別對應於顏色R、G、B。

biBitCount=32 表示位圖最多有232種顏色。這種位圖的結構與16位位圖結構非常類似,當biCompression成員的值是BI_RGB時,它也沒有調色板,32位 中有24位用於存放RGB值,順序是:最高位—保留,紅8位、綠8位、藍8位。這種格式也被成爲888 32位圖。如果 biCompression成員的值是BI_BITFIELDS時,原來調色板的位置將被三個DWORD變量佔據,成爲紅、綠、藍掩碼,分別用於描述紅、 綠、藍分量在32位中所佔的位置。在Windows 95(or 98)中,系統只接受888格式,也就是說三個掩碼的值將只能是:0xFF0000、0xFF00、0xFF。而在NT系統中,你只要注意使掩碼之間不產 生重疊就行。(注:這種圖像格式比較規整,因爲它是DWORD對齊的,所以在內存中進行圖像處理時可進行彙編級的代碼優化(簡單))。

(3) ClrUsed

BITMAPINFOHEADER 結構中的成員ClrUsed指定實際使用的顏色數目。如果ClrUsed設置成0,位圖使用的顏色數目就等於biBitCount成員中的數目。請注意, 如果ClrUsed的值不是可用顏色的最大值或不是0,則在編程時應該注意調色板尺寸的計算,比如在4位位圖中,調色板的缺省尺寸應該是 16*sizeof(RGBQUAD),但是,如果ClrUsed的值不是16或者不是0,那麼調色板的尺寸就應該是ClrUsed*sizeof (RGBQUAD)。

(4) 圖象數據壓縮

① BI_RLE8:每個象素爲8比特的RLE壓縮編碼,可使用編碼方式和絕對方式中的任何一種進行壓縮,這兩種方式可在同一幅圖中的任何地方使用。

編碼方式:由2個字節組成,第一個字節指定使用相同顏色的象素數目,第二個字節指定使用的顏色索引。此外,這個字節對中的第一個字節可設置爲0,聯合使用第二個字節的值表示:


第二個字節的值爲0:行的結束。

第二個字節的值爲1:圖象結束。

第二個字節的值爲2:其後的兩個字節表示下一個象素從當前開始的水平和垂直位置的偏移量。


絕 對方式:第一個字節設置爲0,而第二個字節設置爲0x03~0xFF之間的一個值。在這種方式中,第二個字節表示跟在這個字節後面的字節數,每個字節包含 單個象素的顏色索引。壓縮數據格式需要字邊界(word boundary)對齊。下面的例子是用16進製表示的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個字節組成,第一個字節指定象素數目,第二個字節包含兩種顏色索引,一個在高4位,另一個在低4位。第一個象素使用高4位的顏色索引,第二個使用低4位的顏色索引,第3個使用高4位的顏色索引,依此類推。

絕對方式:這個字節對中的第一個字節設置爲0,第二個字節包含有顏色索引數,其後續字節包含有顏色索引,顏色索引存放在該字節的高、低4位中,一個顏色索引對應一個象素。此外,BI_RLE4也同樣聯合使用第二個字節中的值表示:

第二個字節的值爲0:行的結束。

第二個字節的值爲1:圖象結束。

第二個字節的值爲2:其後的兩個字節表示下一個象素從當前開始的水平和垂直位置的偏移量。

下面的例子是用16進制數表示的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-位真彩色圖象就不使用彩色表(同樣也包括16位、和32位位 圖),因爲位圖中的RGB值就代表了每個象素難丈2噬碇械難丈囪丈鬧匾耘判潁飪梢願ㄖ允廄絛蛭荒芟允咀愎歡嘌丈南允舊璞趕允靜噬 枷蟆GBQUAD結構描述由R、G、B相對強度組成的顏色,定義如下:

typedef struct tagRGBQUAD { /* rgbq */

BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;

} RGBQUAD;


其中:

rgbBlue 指定藍色強度 rgbGreen 指定綠色強度 rgbRed 指定紅色強度 rgbReserved 保留,設置爲0

4. 位圖數據

緊 跟在彩色表之後的是圖象數據字節陣列。圖象的每一掃描行由表示圖象象素的連續的字節組成,每一行的字節數取決於圖象的顏色數目和用象素表示的圖象寬度。掃 描行是由底向上存儲的,這就是說,陣列中的第一個字節表示位圖左下角的象素,而最後一個字節表示位圖右上角的象素。(只針對與倒向DIB,如果是正向 DIB,則掃描行是由頂向下存儲的),倒向DIB的原點在圖像的左下角,而正向DIB的原點在圖像的左上角。同時,每一掃描行的字節數必需是4的整倍數, 也就是DWORD對齊的。如果你想確保圖像的掃描行DWORD對齊,可使用下面的代碼:

(((width*biBitCount)+31)>>5)<<2

5. 參考書目

《圖象文件格式(上、下)—Windows編程》
《圖像文件格式大全》
《Programming Windows by Charles Petzold》


6. 相關站點

各種格式:http://www.wotsit.org/
各種格式:http://www.csdn.net/
位圖格式:http://www.cica.indiana.edu/graphics/image_specs/bmp.format.txt

〈完〉


 
發佈了30 篇原創文章 · 獲贊 1 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章