C++针对bmp格式解析实例

本文实例讲述了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++程序设计有所帮助。