2010年7月6日 星期二

點陣圖(Bitmap)檔案格式

圖一


圖二


圖三






【註1】此欄原本有多種識別碼,用來識別點陣圖的類型:


'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 並不普及,目前皆在 Windows 上作業,因此 ID 全都是 'BM'。
【註2】此欄原本有多種數值,依作業系統種類而定:


28h - Windows 3.1x, 95, NT, ...


0Ch - OS/2 1.x


F0h - OS/2 2.x


以目前 Windows 常用的點陣圖來說,此欄位數值通常是 28h。


但因為微軟已經制定出了新的點陣圖格式,其中的 Bitmap Info Header 結構變化較大,長度加長,所以最好不要直接使用常數 28h,而是應該從實際檔案中讀取這個數值,才能確保程式相容性。
【註3】高度可能為負值,負值表示掃瞄方向由上而下。


但若高度是負值時,此點陣圖將不能被壓縮!(也就是說 Compression 欄位總是為 0)
【註4】未知的功能...永遠被設為 1。
【註5】16 及 32 位元點陣圖是否使用調色盤必須由 Compression 欄位的數值決定,    請參考 Bitfields 的解說。
【註6】點陣圖壓縮方式有以下四種:BI_RGBBI_RLE8BI_RLE4,以及BI_BITFIELDS
None (BI_RGB)表示此點陣圖資料沒有壓縮,不使用調色盤。
RLE 8bpp (BI_RLE8)每個像素為 8 bit 的 RLE 壓縮編碼(Run-Length Encoding)(總共可使用 256 色)。有「編碼模式」(Encoded Mode)和「絕對模式」(Absolute Mode)兩種方法,可在同一幅圖檔中的任何地方交錯使用。「編碼模式」:由兩個位元組(byte)組成。       第一個位元組指定 "Length"(使用相同顏色的像素數目),第二個位元組指定 "Run"(此像素使用的調色盤索引)。


若第一個位元組為零,則表示特殊意義:


   0x0000 - 表示此列結束


   0x0001 - 表示此點陣圖檔案結束


   0x0002 - 表示其後的兩位元組分別表示下個像素位置與目前像素位置的水平/垂直偏移量。


   0x000x - 表示絕對模式。「絕對模式」:第一個位元組為 0x00,第二個位元組為0x03 ~ 0xFF 之間的數值。


其中第二個位元組表示後續資料的長度(單位為 byte),後續資料的每個位元組都表示單一像素的調色盤索引值。每一模式的編碼長度都必須與字邊界對齊(word-aligned),也就是 2 的倍數。使用「編碼模式」時,由於每組編碼皆為兩個位元組,所以毋需多加處理;但是使用「絕對模式」時,則必須在最後補上適當的 0x00 以使資料長度對齊 2 的倍數。下面是一個 BI_RLE8 的例子:03 01 05 02 00 03 00 01 02 00 02 01 00 02 05 01 02 03 00 00 09 02 00 01這些資料可解讀為:如圖二
RLE 4bpp (BI_RLE4)每個像素為 4-bit 的 RLE 壓縮編碼(總共可使用 16 色)。同樣也有「編碼模式」與「絕對模式」,且可以在同一圖檔中任何地方使用任一模式。


「編碼模式」:由兩個位元組組成。


第一個位元組指定像素數目,第二個位元組包含兩個調色盤索引:


第一個像素使用高 4 位元的索引值、第二個像素使用低 4 位元的索引值、第三個像素又使用高 4 位元的索引值,以此類推。


若第一個位元組為零,則表示特殊意義:


   0x0000 - 表示此列結束


   0x0001 - 表示此點陣圖檔案結束


   0x0002 - 表示其後的兩位元組分別表示下個像素位置與目前像素位置的水平/垂直偏移量。


   0x000x - 表示絕對模式。「絕對模式」:第一個位元組為 0x00,第二個位元組表示後續資料的長度(單位為 byte)。


後續資料的每個位元組都含有兩個調色盤索引值(高 4 及低 4 位元),每個索引值對應一個像素。每一模式的編碼長度仍然必須與字邊界對齊(word-aligned)。使用「編碼模式」時,由於每組編碼皆為兩個位元組,所以毋需多加處理;但是使用「絕對模式」時,則必須在最後補上適當的 0 以使資料長度對齊 2 的倍數。下面是一個 BI_RLE4 的例子:03 11 05 02 00 05 01 23 10 00 02 22 00 02 05 01 02 13 00 00 09 10 00 01這些資料可解讀為:如圖三
1. Bitfileds (BI_BITFIELDS)只有當「Bit Per Pixel」欄位的數值為 16 或 32 時,才會使用 BI_BITFIELDS 這種格式。使用 BI_BITFIELDS 時,點陣圖檔中原本的調色盤位置會被三個 DWORD 佔據,分別代表 R、G、B 三個顏色分量的遮罩(mask)。例如:
1. Bit_Per_Pixel = 16, Compression = BI_RGB(無壓縮),則每個像素的 16 位元之中:最低 5 位元表示藍色分量,中間 5 位元表示綠色分量,接著的高 5 位元則是紅色分量,最高的 1 位元保留不使用。此格式即為 RGB555 格式。
2. Bit_Per_Pixel = 16, Compression = BI_BITFIELDS,紅、綠、藍的 mask 分別為 0xF800, 0x07E0, 0x001F,則每個像素的 16 位元之中:最低 5 位元表示藍色分量,中間 6 位元表示綠色分量,最高 5 位元則是紅色分量,此格式即為 RGB565 格式。
【註7】若沒有壓縮(Compression 欄位為 0),則此欄數值可設為 0。


(我發現許多繪圖軟體根本不看此欄數值,隨便填寫也無所謂,圖檔仍可正常開啟)
【註8】若要換算為 dpi,則將此欄數值要除以39.37(吋/公尺)


例如,此欄數值若為 2834 (pixels per meter),則 2834 ÷ 39.37 = 72 (pixels per inch) = 72 dpi
【註9】此欄表示圖檔實際使用的顏色數目,若數值為 0,表示使用所有調色盤顏色。    如果此欄數值並非「可用顏色的最大值」或者「零」,則需注意調色盤尺寸的計算。


例如,在 4 bpp bitmap 中,調色盤預設尺寸應是 16*4 bytes,但若 Used Color 欄位數值並非 16 或 0,則調色盤尺寸應是 Used_Color_Number * 4 (bytes)。
【註10】當此欄的值等於「顏色數」或者為 0 時,表示所有顏色都一樣重要。
【註11】緊跟在調色盤之後的就是點陣圖資料陣列。


每一掃描列的長度取決於圖檔的寬度及顏色深度(Color Depth),但是每一掃描列的長度必需是 4 byte 的倍數(DWORD-aligned)!


正常的點陣圖掃描列是由底向上儲存的:陣列中的第一個 byte 表示全圖左下角的像素,而最後一個 byte 則表示全圖右上角的像素。但如果是正向掃描(Height 欄位為負值),則掃描方向則是由上而下。
整理 by chiapei@gmail.com






沒有留言:

張貼留言