雲彩掛上的二叉樹 - http://blog.csdn.net/markl22222/archive/2011/04/06/6304318.aspx
與上次簡單的位圖加載不同,這次是完整的位圖格式解析.暫時沒有考慮壓縮格式的位圖.
下面的內容難免有錯誤,各位如發現紕漏請及時指出.
- 1.位圖結構介紹
位圖其實比較複雜,主要是由於各種原因導致的標準拓展和複雜化所致.
從磁盤上加載的BMP圖片屬於設備無關位圖(DIB).通常來講,DIB位圖的基本結構如下:
其中,最上面的BITMAPFILEHEADER可以由後面的BITMAPINFO還原出來,沒有BITMAPFILEHEADER的DIB被成爲"壓縮DIB".這裏的壓縮,指的是DIB的其餘部分在連續的內存空間裏緊挨着存放.
很多用於加載DIB的API,如LoadResource,LoadImage之類,它們返回的DIB句柄就是一個壓縮的DIB.
-
BITMAPFILEHEADER 位圖文件頭
BITMAPFILEHEADER 結構定義:
bfType是BMP文件的簽名.對於目前的BMP文件,此字段只可能是兩個ASCII字符'B'和'M'.其他的字段內容表示的文件僅被用在OS/2系統中.在校驗BMP文件時可以直接通過檢查文件最開頭的16位字符是否爲0x4D42來判斷此文件是否爲BMP文件.
bfSize存儲了整個BMP文件的大小.
bfOffBits是Pixel數據段相對文件最開始的偏移量.
-
BITMAPINFO 位圖信息
BITMAPINFO 結構定義:
BITMAPINFOHEADER爲位圖信息頭.
位圖信息頭的版本相當多,最初的版本是BITMAPCOREHEADER,僅用於OS/2,從Win3.1開始是BITMAPINFOHEADER,被稱爲位圖信息結構版本3;在後面還有配合Win95與NT中新特徵而形成的版本4:BITMAPV4HEADER;以及配合Win98和Win2K中新特徵而形成的版本5:BITMAPV5HEADER.
一般最經常看到的是BITMAPINFOHEADER,我們這裏只簡要介紹BITMAPINFOHEADER.
biSize在這裏必須等於sizeof(BITMAPINFOHEADER),這是用來判斷信息頭版本的標記.其實更高版本的信息頭只是在低版本上做了一些拓展,依然可以用低版本的方式解析.
biWidth與biHeight是以像素爲單位的圖像寬度和高度(BITMAPCOREHEADER中它們的類型是WORD,後面的版本都是LONG).biHeight可能取負值.當biHeight<0時表示像素陣列的掃描線由上至下進行.
biPlanes總是等於1.在MSDN中有這樣的描述:"Specifies the number of planes for the target device. This value must be set to 1".DIB只支持單個位平面的圖像.
biBitCount,表示一個像素所需要的二進制位數.可能有以下取值:1;2;4;8;16;24;32.
biCompression,壓縮格式.BI_RGB與BI_BITFIELDS表示未壓縮的位圖.16位與32位位圖的此字段可以是BI_BITFIELDS,此時在位圖信息頭之後將加入3個DWORD表示如何從Pixel中提取RGB的屏蔽位.
biSizeImage是像素陣列的大小.BI_RGB的位圖此字段可以是0.由於像素字節數組中每個掃描行的字節數必需是4的倍數,不足將會用0補齊,因此真正的像素陣列行大小計算起來有點繞.有個通用的公式可以解決這個問題:pitch = 4 * ( (biWidth * biBitCount + 31) / 32 );當然,還有很多其他的計算方法,這裏就不一一列舉了.最後,biSizeImage = pitch * biHeight;
biClrUsed表示顏色表的項數.
biClrImportant表示顯示位圖實際需要的顏色表項數.
-
Pixel[][] 像素陣列
不同位數的位圖,其像素陣列的存取都有所不同.
1,4,8位位圖的像素陣列中存放的不是像素,而是此像素在顏色表中的索引.通過索引查找顏色表就可以得到這個像素點的顏色值.
16位位圖是最爲麻煩的.不僅位圖數據分555與565(指RGB三個分量在每個16位像素中的排列方法)兩種格式,位圖類型也分BI_RGB與BI_BITFIELDS兩種類型.並且最後得到的RGB數據還需要處理成合適的大小,因爲16位中每個通道只有32或64級,但常規顏色是256級,因此需要按照色深進行轉換.
24位位圖比較簡單,每個24位像素中RGB按888排列,即每個通道一個BYTE.
32位位圖可以比24位位圖多一個Alpha通道(但是不一定),因此可以顯示半透明效果(RGBA).其他讀取同24位位圖一致.
-
2.位圖像素讀取
下面給出各種不同位數位圖像素陣列的讀取方法.
首先是通用的數據預讀取,這裏定義一個宏來完成所有工作:
下面是具體的像素讀取算法.
1位位圖(單色位圖):
4位位圖(16色位圖):
8位位圖(256色位圖):
16位位圖(高彩位圖):
24位位圖(真彩位圖):
32位位圖(增強真彩位圖):
- 3.完整示例代碼
這裏給出的代碼是我個人程序中的代碼,自己單獨使用需要按照自己的需求對其中的一些預定義及底層調用做適當的修改.
全部的圖像解析及底層庫代碼請訪問:http://code.google.com/p/win32-standard-expansion/
- CoderObject.h
- BmpCoder.h