在上一講中,我們詳細介紹了常見圖像文件格式的存儲結構,重點剖析了 BMP 文件格式。本講將深入實戰,講解如何在 VC++ 環境下對 BMP 文件進行讀取、寫入、顯示及像素級操作。數字圖像處理的本質是對每一個像素點應用算法,因此獲取像素亮度值並正確顯示處理結果,是所有圖像處理應用的基石。
雖然當前圖像格式眾多(如 TIFF、JPEG、GIF 等),但 BMP 格式(即設備無關位圖 DIB)因其無壓縮、結構簡單、調色板信息完整等特點,成為數字圖像處理算法驗證與工程應用的首選格式。若需處理其他格式,通常先轉換為 BMP 再進行運算。本系列講座的所有範例均以 256 級灰度、無壓縮的 BMP 圖像為標準對象,掌握此格式操作,其他 BMP 變體將不在話下。
標準 256 級灰度 BMP 圖像中,每個像素佔用 8 位(1 Byte),灰度值範圍 0~255:0 代表純黑,255 代表純白,中間過渡自然。其調色板包含 256 個 RGBQUAD 表項,且每個表項的 R、G、B 三分量數值相等,形成標準灰階映射。文件結構由四部分組成:
為了高效操作位圖,我們採用 MFC 的文檔/視圖架構,並直接調用 Win32 API 以追求執行效率(避免過度封裝帶來的性能損耗)。參考 MSDN 中的 Diblook 範例可深入理解 DIB 操作精髓。
在文檔類 CDibDoc 中聲明關鍵變量:
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) // 計算行字節數(4字節對齊)
HANDLE m_hDIB; // 全局內存句柄,存放完整 DIB 數據
CPalette* m_palDIB; // 調色板對象指針
CSize m_sizeDoc; // 文檔尺寸(即圖像寬高)
同時修改字符串資源 IDR_DibTYPE,使文件對話框支持 *.bmp 和 *.dib 過濾。
利用 MFC 機制,重載 CDibDoc::OnOpenDocument,在用戶選擇文件後自動調用。核心邏輯包括:
BITMAPFILEHEADER 驗證 "BM" 標誌。BITMAPINFOHEADER 獲取寬、高、位深、壓縮標誌等。biBitCount 計算調色板大小並讀取 RGBQUAD 數組。m_hDIB。CPalette,賦給 m_palDIB。m_sizeDoc,通知視圖更新。此過程將磁盤文件轉化為內存中的標準 DIB 結構,為後續的像素訪問、算法處理、顯示繪製奠定堅實基礎。後續講座將詳細講解 OnDraw 中的繪製邏輯、像素指針獲取方法及具體圖像處理算法的實現。