生活随笔
收集整理的這篇文章主要介紹了
Bmp格式与编程读取解析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Bmp格式
DigitalImage圖像類設計
圖像加載函數,通過bmp圖片路徑,加載圖像數據,通過類構造函數來實現。
DigitalImage::DigitalImage(LPCTSTR lpszPath)
{StrCpy(m_FilePath, lpszPath);CFile RdBmp;if (!RdBmp.Open(m_FilePath, CFile::modeRead | CFile::shareDenyWrite)){return;}// 為位圖文件頭分配空間,并初始化為0m_lpBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];memset(m_lpBmpFileHeader, 0, sizeof(BITMAPFILEHEADER));// 讀取位圖文件頭int nCount = RdBmp.Read((void *)m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER));if (nCount != sizeof(BITMAPFILEHEADER)){return;}if (m_lpBmpFileHeader->bfType == 0x4d42)// 判斷此文件是不是位圖文件(“0x4d42”代表“BM”){// 是位圖文件// 計算除位圖文件頭的空間大小,分配空間并初始化為0DWORD dwDibSize = RdBmp.GetLength() - sizeof(BITMAPFILEHEADER);m_lpNotBmpFileHenderData = new BYTE[dwDibSize];memset(m_lpNotBmpFileHenderData, 0, dwDibSize);// 讀取除位圖文件頭的所有數據RdBmp.Read(m_lpNotBmpFileHenderData, dwDibSize);// 關閉位圖文件RdBmp.Close();// 設置位圖信息指針m_lpBmpInfo = (LPBITMAPINFO)m_lpNotBmpFileHenderData;// 設置位圖信息頭指針m_lpBmpInfoHeader = (LPBITMAPINFOHEADER)m_lpNotBmpFileHenderData;// 設置位圖顏色表指針m_lpRgbQuad = (LPRGBQUAD)(m_lpNotBmpFileHenderData + m_lpBmpInfoHeader->biSize);// 如果位圖沒有設置位圖使用的顏色數,設置它if (m_lpBmpInfoHeader->biClrUsed == 0){if (m_lpBmpInfoHeader->biBitCount < 9){UINT dwNumOfColor = (UINT)pow(2, m_lpBmpInfoHeader->biBitCount);m_lpBmpInfoHeader->biClrUsed = dwNumOfColor;}}// 計算顏色表長度DWORD dwRgbQuadLength = 0;if (m_lpBmpInfoHeader->biClrUsed > 256)dwRgbQuadLength = 0;elsedwRgbQuadLength = m_lpBmpInfoHeader->biClrUsed * sizeof(RGBQUAD);// 設置位圖數據指針m_lpData = m_lpNotBmpFileHenderData + m_lpBmpInfoHeader->biSize + dwRgbQuadLength;// 判斷是否有顏色表if (m_lpRgbQuad == (LPRGBQUAD)m_lpData){m_lpRgbQuad = NULL; // 將位圖顏色表指針置空m_bHasRgbQuad = FALSE; // 無顏色表}else{m_bHasRgbQuad = TRUE; // 有顏色表//刪除舊的調色板對象if (m_hPalette != NULL){DeleteObject(m_hPalette);m_hPalette = NULL;}// 申請緩沖區,初始化為0DWORD dwSize = 2 * sizeof(WORD) + m_lpBmpInfoHeader->biClrUsed * sizeof(PALETTEENTRY);LPLOGPALETTE lpLogPalette = (LPLOGPALETTE) new BYTE[dwSize];memset(lpLogPalette, 0, dwSize);// 生成邏輯調色板lpLogPalette->palVersion = 0x300;lpLogPalette->palNumEntries = m_lpBmpInfoHeader->biClrUsed;LPRGBQUAD lpRgbQuad = (LPRGBQUAD)m_lpRgbQuad;for (int i = 0; i < m_lpBmpInfoHeader->biClrUsed; i++){lpLogPalette->palPalEntry[i].peRed = lpRgbQuad->rgbRed;lpLogPalette->palPalEntry[i].peGreen = lpRgbQuad->rgbGreen;lpLogPalette->palPalEntry[i].peBlue = lpRgbQuad->rgbBlue;lpLogPalette->palPalEntry[i].peFlags = 0;lpRgbQuad++;}// 創建邏輯調色板m_hPalette = CreatePalette(lpLogPalette);// 釋放緩沖區delete[] lpLogPalette;// 設置位圖大小(因為很多位圖文件都不設置此項)if (m_lpBmpInfoHeader->biSizeImage == 0){m_lpBmpInfoHeader->biSizeImage = m_lpBmpInfoHeader->biWidth*m_lpBmpInfoHeader->biHeight;}// 位圖有效m_bValid = TRUE;}}else{//非位圖m_bValid = FALSE;}
}
?
2.圖片的顯示,通過兩種方式顯示,通過StretchDIBits函數;
BOOL DigitalImage::Draw(CDC *pDC, CPoint origin, CSize size)
{// 位圖無效,無法繪制,返回錯誤if (!m_bValid){return FALSE;}// 舊的調色板句柄HPALETTE hOldPalette = NULL;// 如果位圖指針為空,則返回FALSEif (m_lpNotBmpFileHenderData == NULL){return FALSE;}// 如果位圖有調色板,則選進設備環境中if (m_hPalette != NULL){hOldPalette = SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);}// 設置位圖伸縮模式pDC->SetStretchBltMode(COLORONCOLOR);// 將位圖在pDC所指向的設備上進行顯示StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,0, 0, m_lpBmpInfoHeader->biWidth, m_lpBmpInfoHeader->biHeight, m_lpData, m_lpBmpInfo, DIB_RGB_COLORS, SRCCOPY);// 恢復舊的調色板if (hOldPalette != NULL){SelectPalette(pDC->GetSafeHdc(), hOldPalette, TRUE);}return TRUE;
}
3.通過SetPixel逐像素顯示。
BOOL DigitalImage::DrawPixel(CDC * pDC, CPoint origin)
{ for (int i = m_lpBmpInfoHeader->biHeight-1; i>=0; i--){for (int j = 0; j < m_lpBmpInfoHeader->biWidth; j++){int index = i*m_lpBmpInfoHeader->biWidth + j;int indexcolor = m_lpData[index];COLORREF color;color = RGB(m_lpRgbQuad[indexcolor].rgbRed, m_lpRgbQuad[indexcolor].rgbGreen, m_lpRgbQuad[indexcolor].rgbBlue);pDC->SetPixel(i, j, color);}}return TRUE;
}
4.運行結果:
對于逐像素顯示的函數,顏色數據解析存在不足,顯示如下,對于存在的錯誤,還需繼續專研。
?
總結
以上是生活随笔為你收集整理的Bmp格式与编程读取解析的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。