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> CMyApptheApp; BOOLCMyApp::InitInstance() { m_pMainWnd=newCMainWindow; m_pMainWnd->ShowWindow(m_nCmdShow); returnTRUE;//必须返回TRUE,否则不会进入消息循环,界面会直接退出 } //CMainWindow BEGIN_MESSAGE_MAP(CMainWindow,CWnd) ON_WM_CREATE() ON_WM_PAINT() ON_COMMAND(IDC_OPEN,OnOpen) END_MESSAGE_MAP() //构造函数 CMainWindow::CMainWindow() { LPCTSTRlpszClassName=::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() { } //消息映射函数 intCMainWindow::OnCreate(LPCREATESTRUCTlpCreateStruct) { //OutputDebugString("oncreate"); CClientDCdc(this); m_hMemDC=::CreateCompatibleDC(dc); m_nWidth=0; m_nHeight=0; //设置菜单 HMENUhMenu=::LoadMenuA(theApp.m_hInstance,(LPCSTR)IDR_MENU); ::SetMenu(m_hWnd,hMenu); return0; } voidCMainWindow::OnNcDestroy() { deletethis; } voidCMainWindow::OnDestroy() { } voidCMainWindow::OnPaint() { CPaintDCdc(this); ::BitBlt(dc,0,0,m_nWidth,m_nHeight,m_hMemDC,0,0,SRCCOPY); } voidCMainWindow::OnOpen() { CFileDialogdlg(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; } LPVOIDlpBase=::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("notbmp"); ::UnmapViewOfFile(lpBase); ::CloseHandle(hFileMap); ::CloseHandle(hFile); } //DWORDbfOffBits=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 CClientDCdc(this); //创建与客户区DC兼容的位图 HBITMAPhBitmap=::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> classCMyApp:publicCWinApp { public: virtualBOOLInitInstance(); }; //CMainWindow classCMainWindow:publicCWnd { public: CMainWindow(); ~CMainWindow(); protected: HDCm_hMemDC;//与客户区兼容的内存DC句柄 UINTm_nWidth;//BMP的宽度 UINTm_nHeight;//BMP的高度 //消息映射 afx_msgvoidOnNcDestroy(); afx_msgintOnCreate(LPCREATESTRUCTlpCreateStruct); afx_msgvoidOnDestroy(); afx_msgvoidOnOpen(); afx_msgvoidOnPaint(); DECLARE_MESSAGE_MAP() };
希望本文所述对大家的C++程序设计有所帮助。