位圖BITMAPINFOHEADER 與BITMAPFILEHEADER: html
先來看BITMAPINFOHEADER,只寫幾個主要的
biSize包含的是這個結構體的大小(包括顏色表)
biWidth和biHeight分別是圖片的長寬
biPlanes是目標繪圖設備包含的層數,必須設置爲1
biBitCount是圖像的位數,例如24位,8位等
biXPelsPerMeter, biYPelsPerMeter 是現實世界中每米包含的像素數 設爲3780便可
biSizeImage 圖像數據的大小 = biWidth X biHeight X biBitCount
---------------------------------------------------------------------------------
再看 BITMAPFILEHEADER
bfType 圖片的類型 必須是BM 填0x4d42即十進制的19778
bfOffBits 從文件頭開始到顏色數據(??)的偏移量 54+sizeof(RGBQUAD)*256
bfSize 圖片的大小,bfOffBits + 長 X 寬 X 位數 例如對於128X128X24位的圖像 bfSize=128X128X24 + 54+sizeof(RGBQUAD)*256
bfReserved1和bfReserved1必須爲0算法
BMP文件結構及其存取
數字圖像在外存儲器設備中的存儲形式是圖像文件,圖像必須按照某個已知的、公認的數據存儲順序和結構進行存儲,才能使不一樣的程序對圖像文件順利進行打開或存盤操做,實現數據共享。圖像數據在文件中的存儲順序和結構稱爲圖像文件格式。目前廣爲流傳的圖像文件格式有許多種,常見的格式包括BMP、 GIF、JPEG、TIFF、PSD、DICOM、MPEG等。在各類圖像文件格式中,一部分是由某個軟硬件廠商提出並被普遍接受和採用的格式,例如 BMP、GIF和PSD格式;另外一部分是由各類國際標準組織提出的格式,例如JPEG、TIFF和DICOM,其中JPEG是國際靜止圖像壓縮標準組織提出的格式,TIFF是由部分廠商組織提出的格式,DICOM是醫學圖像國際標準組織提出的醫學圖像專用格式。
BMP文件是Windows操做系統所推薦和支持的圖像文件格式,是一種將內存或顯示器的圖像數據不通過壓縮而直接按位存盤的文件格式,因此稱爲位圖(bitmap)文件,因其文件擴展名爲BMP,故稱爲BMP文件格式,簡稱BMP文件。本書對圖像的算法編程都是針對BMP圖像文件的,所以在本章中咱們詳細介紹BMP文件結構及其讀寫操做,以加深對圖像數據的理解。 編程
BMP文件整體上由4部分組成,分別是位圖文件頭、位圖信息頭、調色板和圖像數據,如表5-1所示。 數組
表5-1 BMP文件的組成結構數據結構
位圖文件頭(bitmap-file header) 編輯器
位圖信息頭(bitmap-information header) 操作系統
彩色表/調色板(color table) 調試
位圖數據(bitmap-data)orm
下面來詳細看一下每一個組成部分的細節。 htm
1.位圖文件頭(bitmap-file header)
位圖文件頭(bitmap-file header)包含了圖像類型、圖像大小、圖像數據存放地址和兩個保留未使用的字段。
打開WINGDI.h文件,搜索"BITMAPFILEHEADER"就能夠定位到BMP文件的位圖文件頭的數據結構定義。
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
2.位圖信息頭(bitmap-information header)
位圖信息頭(bitmap-information header)包含了位圖信息頭的大小、圖像的寬高、圖像的色深、壓縮說明圖像數據的大小和其餘一些參數。
打開WINGDI.h文件,搜索"tagBITMAPINFOHEADER"就能夠定位到BMP文件的位圖信息頭的數據結構定義。
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
3.彩色表/調色板(color table)
彩色表/調色板(color table)是單色、16色和256色圖像文件所特有的,相對應的調色板大小是二、16和256,調色板以4字節爲單位,每4個字節存放一個顏色值,圖像 的數據是指向調色板的索引。
能夠將調色板想象成一個數組,每一個數組元素的大小爲4字節,假設有一256色的BMP圖像的調色板數據爲:
調色板[0]=黑、調色板[1]=白、調色板[2]=紅、調色板[3]=藍…調色板[255]=黃
圖像數據01 00 02 FF表示調用調色板[1]、調色板[0]、調色板[2]和調色板[255]中的數據來顯示圖像顏色。
在早期的計算機中,顯卡相對比較落後,不必定能保證顯示全部顏色,因此在調色板中的顏色數據應儘量將圖像中主要的顏色按順序排列在前面,位圖信息 頭的biClrImportant字段指出了有多少種顏色是重要的。
每一個調色板的大小爲4字節,按藍、綠、紅存儲一個顏色值。
打開WINGDI.h文件,搜索"tagRGBTRIPLE"就能夠定位到BMP文件的調色板的數據結構定義。
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
4.位圖數據(bitmap-data)
若是圖像是單色、16色和256色,則緊跟着調色板的是位圖數據,位圖數據是指向調色板的索引序號。
若是位圖是16位、24位和32位色,則圖像文件中不保留調色板,即不存在調色板,圖像的顏色直接在位圖數據中給出。
16位圖像使用2字節保存顏色值,常見有兩種格式:5位紅5位綠5位藍和5位紅6位綠5位藍,即555格式和565格式。555格式只使用了15 位,最後一位保留,設爲0。
24位圖像使用3字節保存顏色值,每個字節表明一種顏色,按紅、綠、藍排列。
32位圖像使用4字節保存顏色值,每個字節表明一種顏色,除了原來的紅、綠、藍,還有Alpha通道,即透明色。
若是圖像帶有調色板,則位圖數據能夠根據須要選擇壓縮與不壓縮,若是選擇壓縮,則根據BMP圖像是16色或256色,採用RLE4或RLE8壓縮算法壓縮。
RLE4是壓縮16色圖像數據的,RLE4採用表5-5所示方式壓縮數據。
假設有以下16色位圖數據,共20字節,數據使用了RLE4壓縮:
05 00 04 05 00 08 09 05 04 00 04 05 08 09 04 08 07 01 00 00
數據解壓時首先讀取05,由於05不等於0,因此選擇A方案,根據A方案,05表示後面數據重複的次數,接着讀取00,00表示有兩個顏色索引,每一個索引佔4位,第一個像素在高4位,第二個像素在低4位,即在一個字節中低像素在高位,高像素在低位。05 00解壓後等於00 00 0。
讀取04,選擇A方案,按照上面的操做解析,04是後面數據重複的次數,05是兩個顏色索引,第3個顏色索引爲5,第4個顏色索引爲0。04 05解壓後等於05 05。
讀取00,選擇B方案,讀取08,08表示後面有效的顏色索引數。00 08解壓後等於09 05 04 00。
讀取04,選擇A方案,按照上面的操做解析,04是後面數據重複的次數,05是兩個顏色索引。04 05解壓後等於05 05。
讀取08,選擇A方案,按照上面的操做解析,08是後面數據重複的次數,09是兩個顏色索引。08 09解壓後等於09 09 09 09。
讀 取04,選擇A方案,按照上面的操做解析,04是後面數據重複的次數,08是兩個顏色索引。04 08解壓後等於08 08。
讀取07,選擇A方案,按照上面的操做解析,07是後面數據重複的次數,01是兩個顏色索引。07 01解壓後等於01 01 01 0。
讀取00,選擇B方案,讀取00,00表示後面有效的顏色索引數,0表示無,即解壓完一行數據。
綜合上面的操做,解壓後的數據爲:
00 00 00 50 50 90 50 40 00 50 50 90 90 90 90 80 80 10 10 10
看上去和原來的數據大小同樣,沒有體現到壓縮效果,這是由於上面的例子只選擇了20字節數據,並且這20字節數據中重複的數據很少,使用RLE壓縮 重複數據很少的數據時,有時可能壓縮後的大小反而比原來的數據還大。其實通常狀況下當數據比較多並且重複的時候,使用RLE壓縮效果仍是比較理想的。
RLE8的壓縮方式能夠參考上面的RLE4解壓方法,唯一的區別是RLE8使用1個字節存放顏色索引,而RLE4使用4位存放顏色索引。
結合上面對BMP文件的分析,下面分別對256色和24位色的BMP圖像進行十六進制分析,經過在十六進制編輯器中分析文件結構,可以增長分析文件 的經驗。
如圖5-1和圖5-2所示,分別爲256色BMP圖像cat2.bmp和24位色BMP圖像cat1.bmp。其中cat2.bmp圖像的分辨率爲 200×153,文件大小爲31 680字節。cat1.bmp圖像的分辨率爲200×150,文件大小爲90 056字節。
圖5-1 cat2.bmp圖像
圖5-2 cat1.bmp圖像
現 在來分析cat2.bmp的圖像文件,在Winhex中打開cat2.bmp,如圖5-3所示。
圖5-3 在Winhex中打開cat2.bmp圖像文件
首先分析位圖文件頭的結構,如圖5-4所示。根據 BMP文件的位圖文件頭結構定義分析出cat2.bmp圖像的位圖文件頭中各字段的含義,如表5-6所示。
圖5-4 cat2.bmp圖像文件的位圖文件頭
表5-6 cat2.bmp圖像文件中位圖文件頭各字段的含義
十六進制值
描 述
42 4D:
BM的ASCII值,在Windows中的BMP文件標識符
C0 7B 00 00
7B C0h=31680,是cat2文件的大小
00 00 00 00
保留值,總爲0
36 04 00
436h=1078,是圖像數據的地址,即文件頭+信息頭+調色板的長度
繼續分析接下來的數據,根據BMP文件結構的定義,接下來的數據是位圖信息頭,cat2.bmp圖像文件的位圖信息頭的內容如圖5-5所示。
圖5-5 cat2.bmp圖像的位圖信息頭
表5-7所示爲cat2.bmp圖像文件中位圖信息頭各字段的含義。
表5-7 cat2.bmp圖像文件中位圖信息頭各字段的含義
十六進制值
描 述
28 00 00 00:
cat2.bmp圖像的位圖信息頭大小
C8 00 00 00
00 00 00 C8 = 200,是cat2圖像的寬度,單位像素
99 00 00 00
00 00 00 99 = 153,是cat2圖像的高度,單位像素
01 00
老是1
08 00
00 08 = 8,cat2圖像的色深,即2的8次冪等於256色
00 00 00 00
壓縮方式,0表示不壓縮
8A 77 00 00
00 00 77 8A = 30602,是cat2圖像的圖像數據大小,單位字節
12 0B 00 00
00 00 0B 12 = 2834,cat2圖像的水平分辨率,單位像素/m
12 0B 00 00
00 00 0B 12 = 2834,cat2圖像的垂直
分辨率,單位像素/m
00 00 00 00
cat2圖像使用的顏色數,0表示使用所有顏色
00 00 00 00
cat2圖像中重要的顏色數,0表示全部顏色都重要
繼續分析接下來的數據,根據BMP文件結構的定義,由於cat2.bmp圖像是256色的位圖,因此應該有256個調色板,每一個調色板佔4字節,整 個調色板一共1024字節大小。 cat2.bmp圖像文件的調色板數據如圖5-6和圖5-7所示。
圖5-6 cat2.bmp圖像的調色板地址從00000036h開始存儲
圖5-7 cat2.bmp圖像的調色板數據結束地址是00000435h
從圖5-6和圖5-7中能夠看出,cat2.bmp圖像的調色板地址從00000036h開始到00000435h結束,即00000435h - 00000036h + 1 =400h = 1024。
若是想查看cat2圖像的調色板對應的實際顯示顏色,可使用Adobe Photoshop CS打開cat2.bmp,在Adobe Photoshop CS的菜單欄中選擇"圖像"→"模式"→"顏色表",便可觀看cat2的調色板,如圖5-8所示。
圖5-8 在Adobe Photoshop CS中查看cat2的調色板
圖5-8所示cat2.bmp的調色板顏色和圖5-6中的十六進制數據是一一對應的。在Adobe Photoshop CS的調色板上單擊任何一個像素的顏色便可彈出一個拾色器對話框顯示該像素顏色的詳細組成信息。cat2.bmp調色板和cat2.bmp的十六進制數據 的對應關係如圖5-9所示。
繼續分析接下來的數據,根據BMP文件結構的定義,若是一個圖像有調色板,那麼緊跟在調色板後面的是圖像的數據,這些數據不是實際的顏色值,而是指 向調色板數組的索引,根據索引來獲取調色板中的顏色,如圖5-10所示。
圖5-9 cat2.bmp調色板和cat2.bmp的十六進制數據的對應關係
圖5-10 cat2.bmp的圖像數據
由於cat2.bmp是256色的位圖,即採用了8位色深做爲指向調色板數組的索引,因此根據圖5-10中顯示的數據能夠得知:49 49 49 B1 49 49 49 49 49 99表示cat2.bmp位圖左下角第1個像素的顏色等於調色板[49],第2個像素的顏色等於調色板[49] ,第3個像素的顏色等於調色板[49] ,第4個像素的顏色等於調色板[B1]……依此類推。分析完cat2.bmp圖像以後,接下來分析的是cat1.bmp。
cat1.bmp圖像是24位色圖像,根據BMP文件結構定義得知,cat1.bmp圖像沒有調色板,圖像數據存儲的是實際的顏色數據,每一個像素用 3字節表示,分別是紅綠藍。因爲cat1.bmp和cat2.bmp的位圖文件頭和位圖信息頭結構同樣,因此cat1.bmp的位圖文件頭和位圖信息頭可 以參考上面對cat2.bmp的分析,下面從cat1.bmp的位圖信息頭結束的位置開始分析,如圖5-11所示。
圖5-11 cat1.bmp圖像的圖像數據
從圖5-11能夠看到表示每一個像素的紅綠藍三色的值,實際存放的時候是倒過來存放的,在分析BMP圖像格式時須要注意這點。
經過上面對BMP文件存儲結構的分析發現,BMP文件的位圖文件頭和位圖信息頭存在着大量的重複數據。若是存儲大量同一色深的BMP位圖,必然會浪 費大量存儲空間,因此不少時候遊戲編程人員都會去掉BMP文件頭和信息頭,只保留幾個必要的信息和圖像數據,那麼BMP文件頭和信息頭中哪幾個字段是必須 保留的呢?
使用Winhex的文件比較功能比較兩個24位色深的BMP圖像文件,觀察兩個文件的文件頭和信息頭有什麼不一樣的地方,如圖5-12所示。
圖5-12 使用Winhex比較兩個24位色深的BMP圖像文件
從圖5-12能夠看出,兩個色深相同的BMP圖像的文件頭和信息頭一共有4處不一樣的地方,分別是文件頭的文件大小、信息頭的圖像寬度、圖像高度和圖 像數據大小。
因此不少時候,遊戲編程人員只保留圖像文件的文件大小、圖像寬度、圖像高度和圖像數據大小信息,甚至有時不須要保留文件大小這個數值,使用圖像數據大小數值便可。
在分析未知文件存儲格式時,若是遇到去掉了文件頭的文件時,如上面所說的BMP文件,會給分析未知文件格式帶來必定的困難。這時須要使用十六進制編輯器的文件比較功能,觀察兩個同類的未知文件格式尋找某些潛在的規律,若是實在觀察不出規律的,那隻能使用白盒分析方法,對調用此未知文件格式的程序進行反彙編跟蹤調試了。固然,有時靈感和運氣也很重要。
轉自:http://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html