本文實例講述了C++針對bmp格式解析的方法,分享給大家供大家參考。具體方法如下:
寫這代碼時,容易出現如下錯誤:
1. 忘了on_wm_paint()  一直在界面上畫不出來 
2. 正確寫法
BYTE* pBits = (BYTE*)lpBase + pbitmapFileHeader->bfOffBits; 
寫成了 
BYTE* pBits =  pbitmapFileHeader->bfOffBits;
這里主要是用了前面一篇中的CWnd框架。
.cpp源文件如下:
#include "ReadBMP.h"  
#include "resource.h"  
#include <afxdlgs.h >  
  
CMyApp theApp;  
BOOL CMyApp::InitInstance()  
{  
    m_pMainWnd = new CMainWindow;  
    m_pMainWnd->ShowWindow(m_nCmdShow);  
    return TRUE; //必須返回TRUE,否則不會進入消息循環,界面會直接退出  
}  
  
//CMainWindow  
BEGIN_MESSAGE_MAP(CMainWindow, CWnd)  
ON_WM_CREATE()  
ON_WM_PAINT()  
ON_COMMAND(IDC_OPEN, OnOpen)  
END_MESSAGE_MAP()  
//構造函數  
CMainWindow::CMainWindow()  
{  
    LPCTSTR lpszClassName = ::AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, ::LoadCursorA(NULL, IDC_ARROW), (HBRUSH)(COLOR_3DFACE+1), theApp.LoadIcon(IDI_MAIN));  
    CreateEx(WS_EX_CLIENTEDGE, lpszClassName, "xxx", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL);  
}  
//析構函數  
CMainWindow::~CMainWindow()  
{  
  
}  
//消息映射函數  
int CMainWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{  
    //OutputDebugString("oncreate");  
    CClientDC dc(this);  
    m_hMemDC = ::CreateCompatibleDC(dc);  
    m_nWidth = 0;  
    m_nHeight = 0;  
    //設置菜單  
    HMENU hMenu = ::LoadMenuA(theApp.m_hInstance, (LPCSTR)IDR_MENU);  
    ::SetMenu(m_hWnd, hMenu);  
    return 0;  
}  
  
void CMainWindow::OnNcDestroy( )  
{  
    delete this;  
}  
void CMainWindow::OnDestroy()  
{  
      
}  
void CMainWindow::OnPaint()  
{  
    CPaintDC dc(this);  
    ::BitBlt(dc, 0, 0, m_nWidth, m_nHeight, m_hMemDC, 0, 0, SRCCOPY);  
}  
void CMainWindow::OnOpen()  
{  
    CFileDialog dlg(TRUE);  
    if (IDOK != dlg.DoModal())  
    {  
        return;  
    }  
    HANDLE  hFile = ::CreateFile(dlg.GetPathName(), GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  
    if (INVALID_HANDLE_VALUE == hFile)  
    {  
        return;  
    }  
    HANDLE  hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);  
    if (NULL == hFileMap)  
    {  
        return;  
    }  
    LPVOID lpBase = ::MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);  
    if (NULL == lpBase)  
    {  
        return;  
    }  
    //從頭結構中取三個信息:1.bfOffBits位圖數據在文件中的起始位置,2.m_nWidth圖像的寬,3.m_nHeight圖像的高  
    BITMAPFILEHEADER* pbitmapFileHeader;  
    BITMAPINFO* pbitmapInfo;  
    pbitmapFileHeader = (BITMAPFILEHEADER*)lpBase;  
    if (pbitmapFileHeader->bfType != MAKEWORD('B','M'))  
    {  
        MessageBox("not bmp");  
        ::UnmapViewOfFile(lpBase);  
        ::CloseHandle(hFileMap);  
        ::CloseHandle(hFile);  
    }  
    //DWORD bfOffBits = pbitmapFileHeader->bfOffBits;  
    BYTE* pBits = (BYTE*)lpBase + pbitmapFileHeader->bfOffBits;  
    pbitmapInfo = (BITMAPINFO*)((BYTE*)lpBase + sizeof(BITMAPFILEHEADER));  
    m_nWidth = pbitmapInfo->bmiHeader.biWidth;  
    m_nHeight = pbitmapInfo->bmiHeader.biHeight;  
    //顯示BMP文件到內存設備  
    //得客戶區DC  
    CClientDC dc(this);  
    //創建與客戶區DC兼容的位圖  
    HBITMAP hBitmap = ::CreateCompatibleBitmap(dc, m_nWidth, m_nHeight);  
    if (hBitmap == 0)  
    {  
        return;  
    }  
    //位圖選入內存DC  
    ::SelectObject(m_hMemDC, hBitmap);  
  
    //圖像數據放到建立的DC中  
    ::SetDIBitsToDevice(m_hMemDC, 0, 0, m_nWidth, m_nHeight, 0, 0, 0, m_nHeight, pBits, pbitmapInfo, DIB_RGB_COLORS);  
  
    ::InvalidateRect(m_hWnd, NULL, TRUE);  
    ::DeleteObject(hBitmap);  
  
    ::UnmapViewOfFile(lpBase);  
    ::CloseHandle(hFileMap);  
    ::CloseHandle(hFile);  
  
}
.h頭文件如下:
#include <afxwin.h>  
  
class CMyApp:public CWinApp  
{  
public:  
    virtual BOOL InitInstance();  
};  
  
//CMainWindow  
class CMainWindow:public CWnd  
{  
public:  
    CMainWindow();  
    ~CMainWindow();  
  
protected:  
    HDC m_hMemDC; //與客戶區兼容的內存DC句柄   
    UINT m_nWidth; //BMP的寬度  
    UINT m_nHeight; //BMP的高度  
      
    //消息映射  
    afx_msg void OnNcDestroy( );  
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  
    afx_msg void OnDestroy( );  
    afx_msg void OnOpen();  
    afx_msg void OnPaint();  
    DECLARE_MESSAGE_MAP()  
};
希望本文所述對大家的C++程序設計有所幫助。