生活随笔
收集整理的這篇文章主要介紹了
Bmp格式与编程读取解析
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Bmp格式
DigitalImage圖像類設(shè)計(jì)
圖像加載函數(shù),通過bmp圖片路徑,加載圖像數(shù)據(jù),通過類構(gòu)造函數(shù)來實(shí)現(xiàn)。
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”){// 是位圖文件// 計(jì)算除位圖文件頭的空間大小,分配空間并初始化為0DWORD dwDibSize = RdBmp.GetLength() - sizeof(BITMAPFILEHEADER);m_lpNotBmpFileHenderData = new BYTE[dwDibSize];memset(m_lpNotBmpFileHenderData, 0, dwDibSize);// 讀取除位圖文件頭的所有數(shù)據(jù)RdBmp.Read(m_lpNotBmpFileHenderData, dwDibSize);// 關(guān)閉位圖文件RdBmp.Close();// 設(shè)置位圖信息指針m_lpBmpInfo = (LPBITMAPINFO)m_lpNotBmpFileHenderData;// 設(shè)置位圖信息頭指針m_lpBmpInfoHeader = (LPBITMAPINFOHEADER)m_lpNotBmpFileHenderData;// 設(shè)置位圖顏色表指針m_lpRgbQuad = (LPRGBQUAD)(m_lpNotBmpFileHenderData + m_lpBmpInfoHeader->biSize);// 如果位圖沒有設(shè)置位圖使用的顏色數(shù),設(shè)置它if (m_lpBmpInfoHeader->biClrUsed == 0){if (m_lpBmpInfoHeader->biBitCount < 9){UINT dwNumOfColor = (UINT)pow(2, m_lpBmpInfoHeader->biBitCount);m_lpBmpInfoHeader->biClrUsed = dwNumOfColor;}}// 計(jì)算顏色表長度DWORD dwRgbQuadLength = 0;if (m_lpBmpInfoHeader->biClrUsed > 256)dwRgbQuadLength = 0;elsedwRgbQuadLength = m_lpBmpInfoHeader->biClrUsed * sizeof(RGBQUAD);// 設(shè)置位圖數(shù)據(jù)指針m_lpData = m_lpNotBmpFileHenderData + m_lpBmpInfoHeader->biSize + dwRgbQuadLength;// 判斷是否有顏色表if (m_lpRgbQuad == (LPRGBQUAD)m_lpData){m_lpRgbQuad = NULL; // 將位圖顏色表指針置空m_bHasRgbQuad = FALSE; // 無顏色表}else{m_bHasRgbQuad = TRUE; // 有顏色表//刪除舊的調(diào)色板對象if (m_hPalette != NULL){DeleteObject(m_hPalette);m_hPalette = NULL;}// 申請緩沖區(qū),初始化為0DWORD dwSize = 2 * sizeof(WORD) + m_lpBmpInfoHeader->biClrUsed * sizeof(PALETTEENTRY);LPLOGPALETTE lpLogPalette = (LPLOGPALETTE) new BYTE[dwSize];memset(lpLogPalette, 0, dwSize);// 生成邏輯調(diào)色板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++;}// 創(chuàng)建邏輯調(diào)色板m_hPalette = CreatePalette(lpLogPalette);// 釋放緩沖區(qū)delete[] lpLogPalette;// 設(shè)置位圖大小(因?yàn)楹芏辔粓D文件都不設(shè)置此項(xiàng))if (m_lpBmpInfoHeader->biSizeImage == 0){m_lpBmpInfoHeader->biSizeImage = m_lpBmpInfoHeader->biWidth*m_lpBmpInfoHeader->biHeight;}// 位圖有效m_bValid = TRUE;}}else{//非位圖m_bValid = FALSE;}
}
?
2.圖片的顯示,通過兩種方式顯示,通過StretchDIBits函數(shù);
BOOL DigitalImage::Draw(CDC *pDC, CPoint origin, CSize size)
{// 位圖無效,無法繪制,返回錯(cuò)誤if (!m_bValid){return FALSE;}// 舊的調(diào)色板句柄HPALETTE hOldPalette = NULL;// 如果位圖指針為空,則返回FALSEif (m_lpNotBmpFileHenderData == NULL){return FALSE;}// 如果位圖有調(diào)色板,則選進(jìn)設(shè)備環(huán)境中if (m_hPalette != NULL){hOldPalette = SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);}// 設(shè)置位圖伸縮模式pDC->SetStretchBltMode(COLORONCOLOR);// 將位圖在pDC所指向的設(shè)備上進(jìn)行顯示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);// 恢復(fù)舊的調(diào)色板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.運(yùn)行結(jié)果:
對于逐像素顯示的函數(shù),顏色數(shù)據(jù)解析存在不足,顯示如下,對于存在的錯(cuò)誤,還需繼續(xù)專研。
?
總結(jié)
以上是生活随笔為你收集整理的Bmp格式与编程读取解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。