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