一、 BMP位圖操作
BMP位圖包括位圖文件頭結構BITMAPFILEHEADER、位圖信息頭結構BITMAPINFOHEADER、位圖顏色表RGBQUAD和位圖像素數據四部分。處理位圖時要根據文件的這些結構得到位圖文件大小、位圖的寬、高、實現調色板、得到位圖像素值等等。對于256級灰度圖像每個像素用8bit表示顏色的索引值,這里要注意的一點是在BMP位圖中,位圖的每行像素值要填充到一個四字節邊界,即位圖每行所占的存儲長度為四字節的倍數,不足時將多余位用0填充。
在處理圖像應用程序的文檔類(CdibDoc.h)中聲明如下宏及公有變量:
#define WIDTHBYTES(bits) (((bits) 31) / 32 * 4)//計算圖像每行象素所占的字節數目
HANDLE m_hDIB;//存放位圖數據的句柄
CPalette* m_palDIB;//指向調色板Cpalette類的指針
CSize m_sizeDoc; file://初始化視圖的尺寸
1、 讀取灰度BMP位圖
根據BMP位圖文件的結構,操作BMP位圖文件讀入數據,重載了文擋類的OnOpenDocument函數如下:
BOOL CDibDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
CFile file;
CFileException fe;
if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe))
{
AfxMessageBox("文件打不開");
return FALSE;
}//打開文件
DeleteContents();//刪除文擋
BeginWaitCursor();
BITMAPFILEHEADER bmfHeader;//定義位圖文件頭結構
DWORD dwBitsSize;
HANDLE hDIB;
LPSTR pDIB;
BITMAPINFOHEADER *bmhdr;//指向位圖信息頭結構的指針
dwBitsSize = file.GetLength();//得到文件長度
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) !=
sizeof(bmfHeader))
return FALSE;
if (bmfHeader.bfType != 0x4d42) file://檢查是否為BMP文件
return FALSE;
hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE |
GMEM_ZEROINIT, dwBitsSize);
file://申請緩沖區
if (hDIB == 0)
{
return FALSE;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
file://得到申請的緩沖區的指針
if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) )
{
::GlobalUnlock((HGLOBAL)hDIB);
hDIB=NULL;
return FALSE;
}//讀數據,包括位圖信息、位圖顏色表、圖像像素的灰度值
bmhdr=(BITMAPINFOHEADER*)pDIB;//為指向位圖信息頭結構的指針付值
::GlobalUnlock((HGLOBAL)hDIB);
if ((*bmhdr).biBitCount!=8) file://驗證是否為8bit位圖
return FALSE;
m_hDIB=hDIB;
InitDIBData();
file://自定義函數,根據讀入的數據得到位圖的寬、高、顏色表
file:// 來得到初始化視的尺寸、生成調色板
EndWaitCursor();
SetPathName(lpszPathName);//設置存儲路徑
SetModifiedFlag(FALSE); // 設置文件修改標志為FALSE
return TRUE;
}
2、 灰度位圖數據的存儲
為了將圖像處理后所得到的像素值保存起來,重載了文檔類的OnSaveDocument函數,其具體實現如下:
BOOL CDibDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
CFile file;
CFileException fe;
BITMAPFILEHEADER bmfHdr; // 位圖文件頭結構
LPBITMAPINFOHEADER lpBI; file://指向位圖信息結構的指針
DWORD dwDIBSize;
if (!file.Open(lpszPathName, CFile::modeCreate |
CFile::modeReadWrite | CFile::shareExclusive, &fe))
{
AfxMessageBox("文件打不開");
}//打開文件
BOOL bSuccess = FALSE;
BeginWaitCursor();
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);
if (lpBI == NULL)
return FALSE;
dwDIBSize = *(LPDWORD)lpBI 256*sizeof(RGBQUAD);
// Partial Calculation
DWORD dwBmBitsSize;//BMP文件信息結構所占的字節數
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) *lpBI->biHeight;//
標簽: