📄 bmpviewerdoc.cpp
字号:
// BMPViewerDoc.cpp : implementation of the CBMPViewerDoc class//#include "stdafx.h"#include "BMPViewer.h"#include "BMPViewerDoc.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CBMPViewerDocIMPLEMENT_DYNCREATE(CBMPViewerDoc, CDocument)BEGIN_MESSAGE_MAP(CBMPViewerDoc, CDocument) //{{AFX_MSG_MAP(CBMPViewerDoc) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_ZOOMIN, OnZoomin) ON_COMMAND(ID_ZOOMOUT, OnZoomout) //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CBMPViewerDoc construction/destructionCBMPViewerDoc::CBMPViewerDoc(){ // TODO: add one-time construction code here}CBMPViewerDoc::~CBMPViewerDoc(){ if(flag==1) {
// 释放内存资源 HeapFree(GetProcessHeap(),0,pbi); HeapFree(GetProcessHeap(),0,lpBuf); }}BOOL CBMPViewerDoc::OnNewDocument(){ if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE;}/////////////////////////////////////////////////////////////////////////////// CBMPViewerDoc serializationvoid CBMPViewerDoc::Serialize(CArchive& ar){ if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here }}/////////////////////////////////////////////////////////////////////////////// CBMPViewerDoc diagnostics#ifdef _DEBUGvoid CBMPViewerDoc::AssertValid() const{ CDocument::AssertValid();}void CBMPViewerDoc::Dump(CDumpContext& dc) const{ CDocument::Dump(dc);}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CBMPViewerDoc commandsvoid CBMPViewerDoc::OnFileOpen() { // TODO: Add your command handler code here LPCTSTR lpszFilter="BMP Files(*.bmp)|*.bmp|任何文件|*.*||"; CFileDialog dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL); CString filename; CFile file; BITMAPFILEHEADER bf; //打开文件对话框 if(dlg1.DoModal()==IDOK) { filename=dlg1.GetPathName(); if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==0) { //读取文件失败 AfxMessageBox("无法打开文件!",MB_OK,0); return; } //读取文件头 file.Read(&bf,sizeof(bf)); //判断是否是BMP文件 if(bf.bfType!=0x4d42)//'BM' { AfxMessageBox("非BMP文件!",MB_OK,0); return; } //判断文件是否损坏 if(file.GetLength()!=bf.bfSize) { AfxMessageBox("文件已损坏,请检查!",MB_OK,0); return; } //读文件信息头 file.Read(&bi,sizeof(bi)); //计算调色板数目 numQuad=0; if(bi.biBitCount<24) { numQuad=1<<bi.biBitCount; } //为图像信息pbi申请空间 pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD)); memcpy(pbi,&bi,sizeof(bi)); quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER)); //读取调色板 if(numQuad!=0) { file.Read(quad,sizeof(RGBQUAD)*numQuad); } //为图像数据申请空间 bi.biSizeImage=bf.bfSize-bf.bfOffBits; lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage); //读取图像数据 file.Read(lpBuf,bi.biSizeImage); //图像读取完毕,关闭文件,设置标志 file.Close(); flag=1; zoomfactor=1; lpshowbuf=NULL; PrepareShowdata(); UpdateAllViews(NULL,0,NULL); }}void CBMPViewerDoc::OnZoomin() { // TODO: Add your command handler code here
// 缩小倍数不超过2 if(zoomfactor>1||zoomfactor<-1) zoomfactor--; else if(zoomfactor=1) zoomfactor=-2; PrepareShowdata(); UpdateAllViews(NULL,0,NULL);}void CBMPViewerDoc::OnZoomout() { // TODO: Add your command handler code here
// 放大倍数超过2次还原 if(zoomfactor>=1||zoomfactor<-2) zoomfactor++; else if(zoomfactor=-2) zoomfactor=1; PrepareShowdata(); UpdateAllViews(NULL,0,NULL);}BOOL CBMPViewerDoc::PrepareShowdata(){ BYTE** image; BYTE** originimage; int i,j; int linewidth; if(lpshowbuf!=NULL) HeapFree(GetProcessHeap(),0,lpshowbuf); if(zoomfactor>=1) {//放大 pbi->bmiHeader.biHeight=bi.biHeight*zoomfactor; pbi->bmiHeader.biWidth=bi.biWidth*zoomfactor; //每行四字节补齐,计算每行字节数: linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4; //计算显示图像所需内存大小 pbi->bmiHeader.biSizeImage=linewidth*pbi->bmiHeader.biHeight; //申请内存 lpshowbuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,pbi->bmiHeader.biSizeImage); //生成对lpshowbuf的二维数组索引: image=new BYTE*[pbi->bmiHeader.biHeight]; for(i=0;i<pbi->bmiHeader.biHeight;i++) image[i]=lpshowbuf+i*linewidth; originimage=new BYTE*[bi.biHeight]; for(i=0;i<bi.biHeight;i++) originimage[i]=lpBuf+i*bi.biSizeImage/bi.biHeight; //赋值 if(bi.biBitCount<24) { for(i=0;i<pbi->bmiHeader.biHeight;i++) for(j=0;j<linewidth;j++) image[i][j]=originimage[i/zoomfactor][j/zoomfactor]; } else if(bi.biBitCount==24) {//24位真彩色 for(i=0;i<pbi->bmiHeader.biHeight;i++) for(j=0;j<pbi->bmiHeader.biWidth;j++) { image[i][j*3]=originimage[i/zoomfactor][(j/zoomfactor)*3]; image[i][j*3+1]=originimage[i/zoomfactor][(j/zoomfactor)*3+1]; image[i][j*3+2]=originimage[i/zoomfactor][(j/zoomfactor)*3+2]; } } else {//32位色 for(i=0;i<pbi->bmiHeader.biHeight;i++) for(j=0;j<pbi->bmiHeader.biWidth;j++) { image[i][j*4]=originimage[i/zoomfactor][(j/zoomfactor)*4]; image[i][j*4+1]=originimage[i/zoomfactor][(j/zoomfactor)*4+1]; image[i][j*4+2]=originimage[i/zoomfactor][(j/zoomfactor)*4+2]; image[i][j*4+3]=originimage[i/zoomfactor][(j/zoomfactor)*4+3]; } } } else {//缩小 pbi->bmiHeader.biHeight=bi.biHeight/(-zoomfactor); pbi->bmiHeader.biWidth=bi.biWidth/(-zoomfactor); //每行四字节补齐,计算每行字节数: linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4; //计算显示图像所需内存大小 pbi->bmiHeader.biSizeImage=linewidth*pbi->bmiHeader.biHeight; //申请内存 lpshowbuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,pbi->bmiHeader.biSizeImage); //生成对lpshowbuf的二维数组索引: image=new BYTE*[pbi->bmiHeader.biHeight]; for(i=0;i<pbi->bmiHeader.biHeight;i++) image[i]=lpshowbuf+i*linewidth; originimage=new BYTE*[bi.biHeight]; for(i=0;i<bi.biHeight;i++) originimage[i]=lpBuf+i*bi.biSizeImage/bi.biHeight; //赋值 if(bi.biBitCount<24) { for(i=0;i<pbi->bmiHeader.biHeight;i++) for(j=0;j<linewidth;j++) image[i][j]=originimage[i*(-zoomfactor)][j*(-zoomfactor)]; } else if(bi.biBitCount==24) {//24位真彩色 for(i=0;i<pbi->bmiHeader.biHeight;i++) for(j=0;j<pbi->bmiHeader.biWidth;j++) { image[i][j*3]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*3]; image[i][j*3+1]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*3+1]; image[i][j*3+2]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*3+2]; } } else {//32位色 for(i=0;i<pbi->bmiHeader.biHeight;i++) for(j=0;j<pbi->bmiHeader.biWidth;j++) { image[i][j*4]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*4]; image[i][j*4+1]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*4+1]; image[i][j*4+2]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*4+2]; image[i][j*4+3]=originimage[i*(-zoomfactor)][(j*(-zoomfactor))*4+3]; } } }
return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -