BMP和GIF圖像格式

對於現存的所有的圖像文件格式,我們在這裏主要介紹BMP圖像文件格式,並且文件裏的圖像數據是未壓縮的,因爲圖像的數字化處理主要是對圖像中的各 個像素進行相應的處理,而未壓縮的BMP圖像中的像素數值正好與實際要處理的數字圖像相對應,這種格式的文件最合適我們對之進行數字化處理。請讀者記住, 壓縮過的圖像是無法直接進行數字化處理的,如JPEG、GIF等格式的文件,此時首先要對圖像文件解壓縮,這就要涉及到一些比較複雜的壓縮算法。後續章節 中我們將針對特殊的文件格式如何轉換爲BMP格式的文件問題作專門的論述,經過轉換,我們就可以利用得到的未壓縮的BMP文件格式進行後續處理。對於 JPEG、GIF等格式,由於涉及到壓縮算法,這要求讀者掌握一定的信息論方面的知識,如果展開的話,可以寫一本書,限於篇幅原因,我們只作一般性的講 解,有興趣的朋友可以參考相關書籍資料。

一、BMP文件結構

1. BMP文件組成

BMP文件由文件頭、位 圖信息頭、顏色信息和圖形數據四部分組成。文件頭主要包含文件的大小、文件類型、圖像數據偏離文件頭的長度等信息;位圖信息頭包含圖象的尺寸信息、圖像用 幾個比特數值來表示一個像素、圖像是否壓縮、圖像所用的顏色數等信息。顏色信息包含圖像所用到的顏色表,顯示圖像時需用到這個顏色表來生成調色板,但如果 圖像爲真彩色,既圖像的每個像素用24個比特來表示,文件中就沒有這一塊信息,也就不需要操作調色板。文件中的數據塊表示圖像的相應的像素值,需要注意的 是:圖像的像素值在文件中的存放順序爲從左到右,從下到上,也就是說,在BMP文件中首先存放的是圖像的最後一行像素,最後才存儲圖像的第一行像素,但對 與同一行的像素,則是按照先左邊後右邊的的順序存儲的;另外一個需要讀者朋友關注的細節是:文件存儲圖像的每一行像素值時,如果存儲該行像素值所佔的字節 數爲4的倍數,則正常存儲,否則,需要在後端補0,湊足4的倍數。

2. BMP文件頭

BMP文件頭數據結構含有BMP文件的類型、文件大小和位圖起始位置等信息。其結構定義如下: typedef struct tagBITMAPFILEHEADER
{
WORD bfType; // 位圖文件的類型,必須爲“BM”
DWORD bfSize; // 位圖文件的大小,以字節爲單位
WORD bfReserved1; // 位圖文件保留字,必須爲0
WORD bfReserved2; // 位圖文件保留字,必須爲0
DWORD bfOffBits; // 位圖數據的起始位置,以相對於位圖文件頭的偏移量表示,以字節爲單位
} BITMAPFILEHEADER;該結構佔據14個字節。

3. 位圖信息頭

BMP位圖信息頭數據用於說明位圖的尺寸等信息。其結構如下:

typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本結構所佔用字節數
LONG biWidth; // 位圖的寬度,以像素爲單位
LONG biHeight; // 位圖的高度,以像素爲單位
WORD biPlanes; // 目標設備的平面數不清,必須爲1
WORD biBitCount// 每個像素所需的位數,必須是1(雙色), 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位圖壓縮類型,必須是 0(不壓縮),1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一
DWORD biSizeImage; // 位圖的大小,以字節爲單位
LONG biXPelsPerMeter; // 位圖水平分辨率,每米像素數
LONG biYPelsPerMeter; // 位圖垂直分辨率,每米像素數
DWORD biClrUsed;// 位圖實際使用的顏色表中的顏色數
DWORD biClrImportant;// 位圖顯示過程中重要的顏色數
} BITMAPINFOHEADER;該結構佔據40個字節。


注意:對於BMP文件格式,在處理單色圖像和真彩色圖像的時候,無論圖象數據多麼龐大,都不對圖象數據進行任何壓縮處理,一般情況下,如果位圖採用壓縮格式,那麼16色圖像採用RLE4壓縮算法,256色圖像採用RLE8壓縮算法。

4. 顏色表

顏色表用於說明位圖中的顏色,它有若干個表項,每一個表項是一個RGBQUAD類型的結構,定義一種顏色。RGBQUAD結構的定義如下:

typedef struct tagRGBQUAD {
BYTErgbBlue;// 藍色的亮度(值範圍爲0-255)
BYTErgbGreen; // 綠色的亮度(值範圍爲0-255)
BYTErgbRed; // 紅色的亮度(值範圍爲0-255)
BYTErgbReserved;// 保留,必須爲0
} RGBQUAD;

顏 色表中RGBQUAD結構數據的個數由BITMAPINFOHEADER 中的biBitCount項來確定,當biBitCount=1,4,8時,分別有2,16,256個顏色表項,當biBitCount=24時,圖像爲 真彩色,圖像中每個像素的顏色用三個字節表示,分別對應R、G、B值,圖像文件沒有顏色表項。位圖信息頭和顏色表組成位圖信息,BITMAPINFO結構 定義如下:

typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位圖信息頭
RGBQUAD bmiColors[1]; // 顏色表
} BITMAPINFO;

注 意:RGBQUAD數據結構中,增加了一個保留字段rgbReserved,它不代表任何顏色,必須取固定的值爲“0”,同時,RGBQUAD結構中定義 的顏色值中,紅色、綠色和藍色的排列順序與一般真彩色圖像文件的顏色數據排列順序恰好相反,既:若某個位圖中的一個像素點的顏色的描述爲“00,00, ff,00”,則表示該點爲紅色,而不是藍色。

5. 位圖數據

位圖數據記錄了位圖的每一個像素值或該對應像素的顏色表的索 引值,圖像記錄順序是在掃描行內是從左到右,掃描行之間是從下到上。這種格式我們又稱爲Bottom_Up位圖,當然與之相對的還有Up_Down形式的 位圖,它的記錄順序是從上到下的,對於這種形式的位圖,也不存在壓縮形式。位圖的一個像素值所佔的字節數:當biBitCount=1時,8個像素佔1個 字節;當biBitCount=4時,2個像素佔1個字節;當biBitCount=8時,1個像素佔1個字節;當biBitCount=24時,1個像 素佔3個字節,此時圖像爲真彩色圖像。當圖像不是爲真彩色時,圖像文件中包含顏色表,位圖的數據表示對應像素點在顏色表中相應的索引值,當爲真彩色時,每 一個像素用三個字節表示圖像相應像素點彩色值,每個字節分別對應R、G、B分量的值,這時候圖像文件中沒有顏色表。上面我已經講過了,Windows規定 圖像文件中一個掃描行所佔的字節數必須是4的倍數(即以字爲單位),不足的以0填充,圖像文件中一個掃描行所佔的字節數計算方法:

DataSizePerLine= (biWidth* biBitCount+31)/8;// 一個掃描行所佔的字節數

位圖數據的大小按下式計算(不壓縮情況下):

DataSize= DataSizePerLine* biHeight。

上述是BMP文件格式的說明,搞清楚了以上的結構,就可以正確的操作圖像文件,對它進行讀或寫操作了。

 

-------------------------------------------------------------------------------------------------------------------------

 

GIF圖像文件格式

GIF 圖象格式的全稱爲Graphics Interchange Format,從這個名字可以看出,這種圖像格式主要是爲了通過網絡傳輸圖像而設計的。GIF文件不支持24位真彩色圖像,最多隻能存儲256色的圖像或 灰度圖像;GIF格式文件也無法存儲CMY和HIS模型的圖像數據;另外,GIF圖像文件的各種數據區域一般沒有固定的數據長度和存儲順序,所以爲了方便 程序尋找數據區,將數據區中的第一個字節作爲標誌符;最後需要讀者注意的是GIF文件存儲圖像數據是有二種排列順序:順序排列或交叉排列。交叉排列的方式 適合網絡傳輸,這樣一來允許用戶在不完全掌握圖像數據之前,獲取當前圖像的輪廓數據。

GIF文件格式分爲87和89兩個版本,對於87這個 版本,該文件主要是有五個部分組成,它,們是按順序出現的:文件頭塊、邏輯屏幕描述塊、可選擇的調色板塊、圖像數據塊、最後是標誌文件結束的尾塊,該塊總 是取固定的值3BH。其中第一和第二兩個塊用GIF圖像文件頭結構描述:

GIFHEADER:{
DB Signature; //該字段佔六個字節,爲了用於指明圖像爲GIF格式,前三個字符必須爲“GIF”,後三字符用於指定是哪個版本,87或89。
DW ScreenWidth;//
DW ScreenDepth;//佔兩個字節,以像素爲單位表示圖像的寬、高
DB GlobalFlagByte;//該字節的各個位用於調色版的描述
DB BackGroundColor;//代表圖象的背景顏色的索引
DB AspectRatio;圖像的長寬比
}

GIF 格式中的調色板有通用調色板和局部調色板之分,因爲GIF格式允許一個文件中存儲多個圖像,因此有這兩種調色板,其中通用調色板適於文件中的所有圖像,而 局部調色板只適用於某一個圖像。格式中的數據區域一般分爲四個部分,圖像數據識別區域,局部調色板數據,採用壓縮算法得到的圖象數據區域和結束標誌區域。

在GIF89版本中,它包含七個部分,分別是文件頭、通用調色板數據、圖像數據區和四個補充數據區,它們主要是用於提示程序如何處理圖像的。

 

下面分別介紹各種RGB格式。
¨ RGB1、RGB4、RGB8都是調色板類型的RGB格式,在描述這些媒體類型的格式細節時,通常會在BITMAPINFOHEADER數據結構後面跟着 一個調色板(定義一系列顏色)。它們的圖像數據並不是真正的顏色值,而是當前像素顏色值在調色板中的索引。以RGB1(2色位圖)爲例,比如它的調色板中 定義的兩種顏色值依次爲0x000000(黑色)和0xFFFFFF(白色),那麼圖像數據001101010111…(每個像素用1位表示)表示對應各 像素的顏色爲:黑黑白白黑白黑白黑白白白…。
¨ RGB565使用16位表示一個像素,這16位中的5位用於R,6位用於G,5位用於B。程序中通常使用一個字(WORD,一個字等於兩個字節)來操作一個像素。當讀出一個像素後,這個字的各個位意義如下:
     高字節              低字節
R R R R R G G G     G G G B B B B B
可以組合使用屏蔽字和移位操作來得到RGB各分量的值:
#define RGB565_MASK_RED    0xF800
#define RGB565_MASK_GREEN 0x07E0
#define RGB565_MASK_BLUE   0x001F
R = (wPixel & RGB565_MASK_RED) >> 11;   // 取值範圍0-31
G = (wPixel & RGB565_MASK_GREEN) >> 5; // 取值範圍0-63
B = wPixel & RGB565_MASK_BLUE;         // 取值範圍0-31
¨ RGB555是另一種16位的RGB格式,RGB分量都用5位表示(剩下的1位不用)。使用一個字讀出一個像素後,這個字的各個位意義如下:
     高字節             低字節
X R R R R G G       G G G B B B B B       (X表示不用,可以忽略)
可以組合使用屏蔽字和移位操作來得到RGB各分量的值:
#define RGB555_MASK_RED    0x7C00
#define RGB555_MASK_GREEN 0x03E0
#define RGB555_MASK_BLUE   0x001F
R = (wPixel & RGB555_MASK_RED) >> 10;   // 取值範圍0-31
G = (wPixel & RGB555_MASK_GREEN) >> 5; // 取值範圍0-31
B = wPixel & RGB555_MASK_BLUE;         // 取值範圍0-31
¨ RGB24使用24位來表示一個像素,RGB分量都用8位表示,取值範圍爲0-255。注意在內存中RGB各分量的排列順序爲:BGR BGR BGR…。通常可以使用RGBTRIPLE數據結構來操作一個像素,它的定義爲:
typedef struct tagRGBTRIPLE {
BYTE rgbtBlue;    // 藍色分量
BYTE rgbtGreen;   // 綠色分量
BYTE rgbtRed;     // 紅色分量
} RGBTRIPLE;
¨ RGB32使用32位來表示一個像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。(ARGB32就是帶Alpha通道的 RGB32。)注意在內存中RGB各分量的排列順序爲:BGRA BGRA BGRA…。通常可以使用RGBQUAD數據結構來操作一個像素,它的定義爲:
typedef struct tagRGBQUAD {
BYTE    rgbBlue;      // 藍色分量
BYTE    rgbGreen;     // 綠色分量
BYTE    rgbRed;       // 紅色分量
BYTE    rgbReserved; // 保留字節(用作Alpha通道或忽略)
} RGBQUAD;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章