位元影像一共有兩種類型,即:裝置相關位元影像(DDB)和裝置無關位元影像(DIB)。DDB位元影像在早期的Windows系統(Windows 3.0以前)中是很普遍的,事實上它也是唯一的。然而,隨著顯示器製造技術的進步,以及顯示裝置的多樣化,DDB位元影像的一些固有的問題開始浮現出來了,象BitBlt()這種函數就是基於DDB位元影像的。比如,它不能夠儲存(或者說擷取)建立這張圖片的原始裝置的分辯率,這樣,應用程式就不能快速的判斷客戶機的顯示裝置是否適合顯示這張圖片。為瞭解決這一難題,微軟建立了DIB位元影像格式。
BMP檔案是Windows儲存映像的一種通用檔案格式,在數位影像處理方面佔有重要的地位。BMP檔案中儲存的映像資料是一種DIB(Device-Independent Bitmap,即裝置無關位元影像),DIB是標準的Windows位元影像格式,它內建顏色資訊,因此調色盤管理非常容易。
BMP檔案的結構
DIB位元影像包含下列的顏色和尺寸資訊:
* 原始裝置(即建立圖片的裝置)的顏色格式。
* 原始裝置的分辯率。
* 原始裝置的調色盤
* 一個位元組,由紅、綠、藍(RGB)三個值代表一個像素。
* 一個數組壓縮標誌,用於表明資料的壓縮方案(如果需要的話)。
以上這些資訊儲存在BITMAPINFO結構中,該結構由BITMAPINFOHEADER結構和兩個或更多個RGBQUAD結構所組成。BITMAPINFOHEADER結構所包含的成員表明了映像的尺寸、原始裝置的顏色格式、以及資料壓縮方案等資訊。RGBQUAD結構標識了像素所用到的顏色資料。
位元影像檔案的組成 結構名稱 符號
位元影像檔案頭(bitmap-file header)BITMAPFILEHEADERbmfh
位元影像資訊頭(bitmap-information header)BITMAPINFOHEADERbmih
彩色表(color table)RGBQUADaColors[]
圖象資料陣列位元組BYTEaBitmapBits[]
位元影像檔案形式化結構
位移量 域的名稱 大小 內容
圖象檔案
頭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”就行。
0002hFile Size1 dword用位元組表示的整個檔案的大小
0006hReserved1 dword保留,必須設定為0
000AhBitmap Data Offset1 dword從檔案開始到位元影像資料開始之間的資料(bitmap data)之間的位移量
位元影像資訊頭000EhBitmap Header Size1 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,而是應該從具體的檔案中讀取這個值。這樣才能確保程式的相容性。
0012hWidth1 dword位元影像的寬度,以象素為單位
0016hHeight1 dword位元影像的高度,以象素為單位
001AhPlanes1 word位元影像的位面數(註:該值將總是1)
001ChBits Per Pixel1 word每個象素的位元
1 - 單色位元影像(實際上可有兩種顏色,預設情況下是黑色和白色。你可以自己定義這兩種顏色)
4 - 16 色位元影像
8 - 256 色位元影像
16 - 16bit 高彩色位元影像
24 - 24bit 真彩色位元影像
32 - 32bit 增強型真彩色位元影像
001EhCompression1 dword壓縮說明:
0 - 不壓縮 (使用BI_RGB表示)
1 - RLE 8-使用8位RLE壓縮方式(用BI_RLE8表示)
2 - RLE 4-使用4位RLE壓縮方式(用BI_RLE4表示)
3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)
0022hBitmap Data Size1 dword用位元組數表示的位元影像資料的大小。該數必須是4的倍數
0026hHResolution1 dword用象素/米表示的水平解析度
002AhVResolution1 dword用象素/米表示的垂直解析度
002EhColors1 dword位元影像使用的顏色數。如8-位元/象素表示為100h或者 256.
0032hImportant Colors1 dword指定重要的顏色數。當該域的值等於顏色數時(或者等於0時),表示所有顏色都一樣重要
調色盤資料根據BMP版本的不同而不同PaletteN * 4 byte調色盤規範。對於調色盤中的每個表項,這4個位元組用下述方法來描述RGB的值:
1位元組用於藍色分量
1位元組用於綠色分量
1位元組用於紅色分量
1位元組用於填充符(設定為0)
圖象資料根據BMP版本及調色盤尺寸的不同而不同Bitmap Dataxxx bytes該域的大小取決於壓縮方法及映像的尺寸和映像的位元深度,它包含所有的位元影像資料位元組,這些資料可能是彩色調色盤的索引號,也可能是實際的RGB值,這將根據映像資訊頭中的位元深度值來決定。
位元影像檔案程式結構
BITMAPFILEHEADER
位元影像檔案頭
(只用於BMP檔案)
bfType = “BM”(0x4D42)
bfSize
bfReserved1
bfReserved2
bfOffBits
BITMAPINFOHEADER
位元影像資訊頭
biSize
biWidth
biHeight
biPlance
biBitCount
biCompression
biSizeImage
biXPelsPerMeter
biYPelsPerMeter
biClrUsed
biClrImportant
Palette
調色盤
單色DIB有2個表項
16色DIB有16個表項或更少
256色DIB有256個表項或更少
真彩色DIB沒有調色盤
DIB Pixels
DIB映像資料
象素按照每行每列的順序排列
每一行的位元組數必須是4的整倍數
位元影像讀寫
寫bitmap的一般過程:
1:申明BITMAPFILEHEADER,並清空該結構:
BITMAPFILEHEADER bfh;
memset( &bfh, 0, sizeof( bfh ) );
2:初始化該結構:
bfn.bfType = 'MB'; // Bitmap
//說明該檔案的大小,cbBuffer為位元影像資料的大小
bfn.bfSize = sizeof(bfn) + cbBuffer + sizeof(BITMAPINFOHEADER);
//說明位元影像檔案資料在整個位元影像檔案中的位移,即資料是從哪兒開始的
bfn.bfOffBits = sizeof(BITMAPINFORHEADER) + sizeof(BITMAPFILEHEADER);
3:將bfn寫入檔案
4:申明BITMAPINFOHEADER,並清空該結構:
BITMAPINFOHEADER bih;
memset( &bih, 0, sizeof( bih ) );
5:初始化該結構:
bih.biSize = sizeof( bih );
bih.biWidth = biWidth; //位元影像的寬度
bih.biHeight = biHeight; //位元影像的高度
bih.biPlanes = biPlanes; //位元影像的位面數
bih.biBitCount = biBitCount; //位元影像的色深
6:將bih寫入檔案
7:最後寫入資料就行了。
讀位元影像:(虛擬碼)
If open Bitmap file
Read two bytes (type) and if different than 0x4D42 stop
Ignore eight bytes
Read four bytes (start of image data)
Ignore four bytes
Read four bytes (width of bitmap)
Read four bytes (height of bitmap)
Ignore two bytes
Read two bytes (bit count of bitmap) and if different than 24 stop
Read four bytes (compression of bitmap) and if different than BI_RGB stop
Move to start of image data
Allocate memory for image data (3(one byte for red, other for
green other for blue) * ImageWidth * ImageHeight)
Read (3 * ImageWidth * ImageHeight) bytes from file to buffer
Swap the red and blue components of buffer
If ImageHeight is negative
Flip the buffer lines
End if
Close file