MFC对话框打开一幅图片并在picture显示和图片保存

学了MFC一段时间后,试着要用对话框打开一幅bmp图像并保存,结果发现网上这些资料太少了,而且有的也讲不清,讲不全,所以自己磕磕碰碰捣鼓了好久,期间也谢谢各位大神的指导,现在我终于完成,特意写出来与大家分享,各位菜鸟共勉。

一、首先要先了解bmp位图结构

http://wenku.baidu.com/view/d06c23543c1ec5da50e2706d.html

可以去看看,内容不多但是够看,也容易懂

二、了解位图的显示函数

SetStretchBltMode()

StretchDIBits()具体函数介绍自己百度一下,我就不多说了

三、开始做啦

1、新建一个MFC对话框文档

默认其他设置,点击完成后会出现这个界面

在按钮上单击鼠标右键,在弹出的列表中选择属性 把标题改为读取图片

再添加一个按钮,把ID改为IDC_SAVE,标题改为保存图片

在控件中选择图像,然后在对话框画一个大小适宜的矩形框,在选中对话框点击右键,选择属性,把ID改为IDC_PICTURE

回到对话框界面,双击读取图片按钮,这时会弹出一个对话框,点确定然后就会跳到关联函数这边了

先把CDialog::OnOK();注释起来,这个是点击按钮后对话框就会关闭的函数

然后在//   CDialog::OnOK();下面添加以下代码

代码都有注释,不懂的地方可以自己再百度

     //CFileDialogVC中打开文件对话框类

       BITMAPFILEHEADER bmpHeader;//文件头

       BITMAPINFOHEADER bmpInfo;//信息头

       CFileDialog dlg(TRUE, "*.BMP", NULL,NULL,"位图文件(*.BMP)|*.bmp;*.BMP|",this);

       CFile bmpFile;//记录打开文件

   CString strFileName;//记录选择文件路径

       if (!dlg.DoModal() == IDOK) return;

       strFileName = dlg.GetPathName();

       //以只读的方式打开文件

       if(!bmpFile.Open(strFileName, CFile::modeRead|CFile::typeBinary))return;

       if (bmpFile.Read(&bmpHeader,sizeof(BITMAPFILEHEADER))!= sizeof(BITMAPFILEHEADER))

       {

              AfxMessageBox("readbmp header failed!");

              return;

       }

       if (bmpHeader.bfType != 0x4d42)

       {

              AfxMessageBox("invalidfile type!");

              return;

       }

       if (bmpFile.Read(&bmpInfo,sizeof(BITMAPINFOHEADER))!= sizeof(BITMAPINFOHEADER))

       {

              AfxMessageBox("readbmp infor header failed!");

              return;

       }

       if (bmpInfo.biBitCount != 24)

       {

       AfxMessageBox("File is not 24 bit.Applicationdoesn't support this kind of file!");

       return;

       }

       pBmpInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)];

       if (!pBmpInfo)

       {

              AfxMessageBox("memoryerror!");

              return;

       }

   //为图像数据申请空间

       memcpy(pBmpInfo,&bmpInfo,sizeof(BITMAPINFOHEADER));

       DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;

       pBmpData = (BYTE*)new char[dataBytes];

       if (!pBmpData)

       {

              AfxMessageBox("memoryerror!");

              delete pBmpData;

              return;

       }

       if (bmpFile.Read(pBmpData,dataBytes) != dataBytes)

       {

              AfxMessageBox("Readbmp data failed!");

              delete pBmpInfo;

              delete pBmpData;

              return;

       }

       bmpFile.Close();

       CWnd *pWnd=GetDlgItem(IDC_PICTURE);//获得pictrue控件窗口的句柄

       CRect rect;

       pWnd->GetClientRect(&rect);//获得pictrue控件所在的矩形区域

       CDC *pDC=pWnd->GetDC();//获得pictrue控件的DC

    //显示图片

       pDC->SetStretchBltMode(COLORONCOLOR);

StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpInfo.biWidth,bmpInfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);

       iBmpWidth=bmpInfo.biWidth;                    

       iBmpHeight=bmpInfo.biHeight;

然后在这个.cpp文件头处添加

BITMAPINFO* pBmpInfo;     //记录图像细节

BYTE* pBmpData;           //图像数据

 

int iBmpWidth;       // 输入的宽度,以像素为单位

int iBmpHeight;     // 输入的高度,以像素为单位

这些是全局变量,主要是为了后面图像保存可以用的

 

再回到对话框界面,双击保存图片按钮,这时会弹出一个对话框,点确定然后就会跳到关联函数这边了

       在// TODO: Add your control notificationhandler code here下添加下面这些代码

       BITMAPFILEHEADER bmpf;//文件头

       BITMAPINFOHEADER bmpi;//信息头

       int Widthbytes;

       CFile bmpFile;

       CString strFileName;

       CFileDialog dlg(FALSE, "*.BMP", NULL,NULL,"位图文件(*.BMP)|*.bmp;*.BMP|");

       if (!dlg.DoModal() == IDC_SAVE)return;

       strFileName = dlg.GetPathName();

       if (bmpFile.Open(strFileName, CFile::modeCreate |CFile::modeReadWrite)== 0) return ;

       Widthbytes = (iBmpWidth*3+3)/4*4;//位图对齐,确保为4的倍数

 

       /* BITMAPFILEHEADER结构填写 */

       bmpf.bfType =0x4d42;

       bmpf.bfOffBits =sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER);

       bmpf.bfSize = bmpf.bfOffBits + Widthbytes *iBmpHeight;

       bmpf.bfReserved1 =0;

       bmpf.bfReserved2 =0;

       /* BITMAPINFOHEADER结构填写 */

       bmpi.biSize = sizeof(BITMAPINFOHEADER);

       bmpi.biWidth = iBmpWidth;

       bmpi.biHeight =iBmpHeight;

       bmpi.biPlanes = 1;

       bmpi.biBitCount =24;//24

       bmpi.biCompression= BI_RGB;

       bmpi.biSizeImage=0;

       bmpi.biXPelsPerMeter= 0;

       bmpi.biYPelsPerMeter= 0;

       bmpi.biClrUsed = 0;

       bmpi.biClrImportant= 0;

       bmpFile.Write(&bmpf,sizeof(bmpf));//写文件头;

       bmpFile.Write(&bmpi,sizeof(bmpi));//写信息头;

       bmpFile.Write(pBmpData,Widthbytes*iBmpHeight);//写图像数据信息;

       bmpFile.Close();   

OK全部完成了,编译运行一下,点击打开图片按钮就能显示图片了

呵呵,写得不够专业,还望大家不吝赐教

猜你喜欢

转载自blog.csdn.net/LYYLYQLJD/article/details/10601317
今日推荐