MFC—PictureControl控件使用,显示和处理图像

转载地址:http://b217dgy.blog.51cto.com/5704306/1332787/

在《OpenCV教程-基础篇》的2.8节中,所创建的MFC图像显示是直接放在对话框面板的左上角的,感觉不大美观。在MFC快速应用opencv一书中则是介绍用SDI(单文档界面)来显示图像,A step-by-step guide to the use of Microsoft Visual C++ and theIntel OpenCV library使用VS2005来进行图像和视频的读取和处理,但是其图像和视频的显示界面不是在对话框里面的,而是新建一个窗口来做。所以下面我们就来看看怎么在对话框里使用Picture控件来显示和处理图像。

创建MFC

首先创建一个MFC对话框应用程序(Dialog-based Application)如下:

Image:mfc_picctl_1.JPG

Image:mfc_picctl_2.JPG


在VS2005和2008里,我们可以用一个 Solution 来组合几个 Project (每个 Project 基本上只包含一个 Program),当我们要构建一个多Program的应用时(例如一个客户端程序加一个服务器应用程序),利用 Solution 可以将这些 Projects 组合起来、并且共享文件和函数库。通常需要为Solution创建一个主路径,其中包含了所有Projects的路径。不过在这篇文章里,我们只构建一个简单的Project,所以在创建MFC的New Project对话框里,不用勾选“Create directory for solution”这个选项。

点击OK -- Next进入下一步,在这里我们创建一个Dialog-based Application,大部分选项按默认设置就行,不过最下面的“Use Unicode libraries”最好去掉。如果勾选了这个选项,程序代码就会使用16bit的Unicode字符集来编码,但是很多函数虽然使用 char* (ASCII stings) 类型字符,而将字符串从 Unicode 转换到 ASCII 是非常麻烦的。使用 Unicode 在编译时可能会遇到下列错误:

  1. cannot convert parameter "padding:0px; margin:0px; color:rgb(0,0,221)">1 from "padding:0px; margin:0px; color:rgb(255,0,0)">'CString' to "padding:0px; margin:0px; color:rgb(255,0,0)">'const char *'  
  2. cannot convert from "padding:0px; margin:0px; color:rgb(255,0,0)">'const char [11]' to "padding:0px; margin:0px; color:rgb(255,0,0)">'LPCWSTR'  
MFC—PictureControl控件使用,显示和处理图像
cannot convert parameter  from  to 
cannot convert from  to 

这意味着在Unicode和Multi-byte字符串的转换中出现了问题。在上一篇学习笔记中,就提到“成员函数LoadBMP其输入参数类型应为 const char*”,那应该只是一个治标的方法,这里的去掉“Use Unicode libraries”选项,才是治本之道。 往后的几步设置,可以根据自己的需要来操作,我的设置如下:

Image:mfc_picctl_3.JPG

Image:mfc_picctl_4.JPG


[ 编辑]

编写代码

在Resource View面板->mymfc(工程名称)->mymfc.rc->Dialog双击IDD_MYMFC_DIALOG,可以看到一个初始的GUI界面,往里面添加两个 Button 和 一个 Picture 控件,如下:

Image:mfc_picctl_5.JPG

选中单个控件、右击选择属性(Properties),可以看到控件的ID号,这个号可以自行编辑,例如 Picture 控件的 ID 号我设置为 IDC_ShowImg,这个 ID 号在后面的图像显示函数中要用到。 首先在项目属性中加载lib文件:菜单Project -> Properties -> Configuration Properties -> Linker –> Input -> additional dependencies 中加入 cxcore200.lib cv200.lib highgui200.lib。 然后在 mymfc.h 的 #include "resource.h" 下加入如下代码:

  1. "padding:0px; margin:0px; color:rgb(51,153,51)">#include "cv.h""padding:0px; margin:0px; color:rgb(51,153,51)">#include "highgui.h""padding:0px; margin:0px; color:rgb(51,153,51)">#define IMAGE_WIDTH 256"padding:0px; margin:0px; color:rgb(51,153,51)">#define IMAGE_HEIGHT 256"padding:0px; margin:0px; color:rgb(51,153,51)">#define IMAGE_CHANNELS 3  
MFC—PictureControl控件使用,显示和处理图像

在 Class View 面板右击 CmymfcDlg,选择 Add –> Add Variable,添加一个 IplImage* 类型的变量 TheImage;再点击 CmymfcDlg,在下面窗口的列表中双击 OnInitDialog,在“// TODO: Add extra initialization here”下面添加 TheImage 的初始化代码:

  1. CvSize ImgSize"padding:0px; margin:0px; color:rgb(51,153,51)">;  
  2. ImgSize."padding:0px; margin:0px; color:rgb(32,32,32)">height"padding:0px; margin:0px; color:rgb(51,153,51)">= IMAGE_HEIGHT"padding:0px; margin:0px; color:rgb(51,153,51)">;  
  3. ImgSize."padding:0px; margin:0px; color:rgb(32,32,32)">width"padding:0px; margin:0px; color:rgb(51,153,51)">= IMAGE_WIDTH"padding:0px; margin:0px; color:rgb(51,153,51)">;  
  4. TheImage "padding:0px; margin:0px; color:rgb(51,153,51)">= cvCreateImage"padding:0px; margin:0px; color:rgb(0,153,0)">( ImgSize"padding:0px; margin:0px; color:rgb(51,153,51)">, IPL_DEPTH_8U"padding:0px; margin:0px; color:rgb(51,153,51)">, IMAGE_CHANNELS "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;  
MFC—PictureControl控件使用,显示和处理图像
CvSize ImgSize
ImgSize. IMAGE_HEIGHT
ImgSize. IMAGE_WIDTH
TheImage  cvCreateImage ImgSize IPL_DEPTH_8U IMAGE_CHANNELS 

然后双击 OnPaint,在 if(IsIconic())…的 else 里添加以下代码,用来重绘窗口:

  1. CDialog"padding:0px; margin:0px; color:rgb(51,153,51)">::"padding:0px; margin:0px; color:rgb(32,32,32)">OnPaint"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 重绘对话框  
  2. CDialog"padding:0px; margin:0px; color:rgb(51,153,51)">::"padding:0px; margin:0px; color:rgb(32,32,32)">UpdateWindow"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 更新windows窗口,如果无这步调用,图片显示还会出现问题  
  3. ShowImage"padding:0px; margin:0px; color:rgb(0,153,0)">( TheImage"padding:0px; margin:0px; color:rgb(51,153,51)">, IDC_ShowImg "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 重绘图片函数  
MFC—PictureControl控件使用,显示和处理图像
CDialog
CDialog
ShowImage TheImage IDC_ShowImg 

接着在 CmymfcApp 下面的成员列表中双击 InitInstance,在两个“// TODO: Place code here to handle when the dialog is…”下面添加:

  1. cvReleaseImage"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(51,153,51)">&dlg."padding:0px; margin:0px; color:rgb(32,32,32)">TheImage"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;  
MFC—PictureControl控件使用,显示和处理图像
cvReleaseImagedlg.

即按下“OK”或“Cancel”时,释放TheImage占用的内存。 接下来就是写读取和处理图片的功能函数了。 回到 mymfc 的 GUI 编辑界面中,右击按钮 ReadImg,选择 Add Event Handler,建立按钮点击的消息响应程序:

Image:mfc_picctl_6.JPG

句柄名设置为 OnBnClickedReadimg,主要的响应操作包括 弹出对话框选择图片文件、读入图片文件、对图片统一缩放至256*256的大小、显示图像,代码如下:

  1. "padding:0px; margin:0px; color:rgb(102,102,102)">// TODO: Add your control notification handler code here// 选项图片的约定  
  2.     CFileDialog dlg"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; font-weight:bold">TRUE"padding:0px; margin:0px; color:rgb(51,153,51)">, _T"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(255,0,0)">"*.bmp""padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">,"padding:0px; margin:0px; font-weight:bold">NULL"padding:0px; margin:0px; color:rgb(51,153,51)">,  
  3.         OFN_FILEMUSTEXIST "padding:0px; margin:0px; color:rgb(51,153,51)">| OFN_PATHMUSTEXIST "padding:0px; margin:0px; color:rgb(51,153,51)">| OFN_HIDEREADONLY"padding:0px; margin:0px; color:rgb(51,153,51)">,  
  4.         _T"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(255,0,0)">"image files (*.bmp; *.jpg) |*.bmp; *.jpg | All Files (*.*) |*.*||""padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">,"padding:0px; margin:0px; font-weight:bold">NULL"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 打开文件对话框的标题名  
  5.     dlg."padding:0px; margin:0px; color:rgb(32,32,32)">m_ofn."padding:0px; margin:0px; color:rgb(32,32,32)">lpstrTitle"padding:0px; margin:0px; color:rgb(51,153,51)">= _T"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(255,0,0)">"Open Image""padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 判断是否获得图片if( dlg.DoModal()!= IDOK )return;// 获取图片路径  
  6.     CString mPath "padding:0px; margin:0px; color:rgb(51,153,51)">= dlg."padding:0px; margin:0px; color:rgb(32,32,32)">GetPathName"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 读取图片、缓存到一个局部变量 ipl 中  
  7.     IplImage"padding:0px; margin:0px; color:rgb(51,153,51)">* ipl "padding:0px; margin:0px; color:rgb(51,153,51)">= cvLoadImage"padding:0px; margin:0px; color:rgb(0,153,0)">( mPath"padding:0px; margin:0px; color:rgb(51,153,51)">,"padding:0px; margin:0px; color:rgb(0,0,221)">1"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 判断是否成功读取图片if(!ipl )return;// 对上一幅显示的图片数据清零if( TheImage )cvZero( TheImage );// 对读入的图片进行缩放,使其宽或高最大值者刚好等于 256,再复制到 TheImage 中  
  8.     ResizeImage"padding:0px; margin:0px; color:rgb(0,153,0)">( ipl "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 调用显示图片函数  
  9.     ShowImage"padding:0px; margin:0px; color:rgb(0,153,0)">( TheImage"padding:0px; margin:0px; color:rgb(51,153,51)">, IDC_ShowImg "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 释放 ipl 占用的内存  
  10.     cvReleaseImage"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(51,153,51)">&ipl "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;  
MFC—PictureControl控件使用,显示和处理图像

        CFileDialog dlg _T
                OFN_FILEMUSTEXIST  OFN_PATHMUSTEXIST  OFN_HIDEREADONLY
                _T
        dlg.. _T dlg. IDOK 
        CString mPath  dlg.
        IplImage ipl  cvLoadImage mPathipl  TheImage cvZero TheImage 
        ResizeImage ipl 
        ShowImage TheImage IDC_ShowImg 
        cvReleaseImageipl 

其中包含了两个新的成员函数 ResizeImage 和 ShowImage,前者的作用是对读入的不同大小的图像进行缩放,再通过设置 ROI 的方式将图像存入 256*256 的 TheImage 中;后者是将图像 TheImage 显示到图片显示控件 IDC_ShouImg 窗口的正中部位。为了实现这两个功能,首先在 Class View 面板右击 CmymfcDlg,选择 Add –> Add Function,创建两个函数:void ShowImage( IplImage* img, UINT ID ) 和 void ResizeImage(IplImage* img)。以下是这两个函数的实现代码:

  1. "padding:0px; margin:0px; color:rgb(153,51,51)">void CmymfcDlg"padding:0px; margin:0px; color:rgb(51,153,51)">::"padding:0px; margin:0px; color:rgb(32,32,32)">ResizeImage"padding:0px; margin:0px; color:rgb(0,153,0)">(IplImage"padding:0px; margin:0px; color:rgb(51,153,51)">* img"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(0,153,0)">{"padding:0px; margin:0px; color:rgb(102,102,102)">// 读取图片的宽和高int w = img->width;int h = img->height;// 找出宽和高中的较大值者int max =(w > h)? w: h;// 计算将图片缩放到TheImage区域所需的比例因子float scale =(float)((float) max /256.0f);// 缩放后图片的宽和高int nw =(int)( w/scale );int nh =(int)( h/scale );// 为了将缩放后的图片存入 TheImage 的正中部位,需计算图片在 TheImage 左上角的期望坐标值int tlx =(nw > nh)?0:(int)(256-nw)/2;int tly =(nw > nh)?(int)(256-nh)/2:0;// 设置 TheImage 的 ROI 区域,用来存入图片 img  
  2.     cvSetImageROI"padding:0px; margin:0px; color:rgb(0,153,0)">( TheImage"padding:0px; margin:0px; color:rgb(51,153,51)">, cvRect"padding:0px; margin:0px; color:rgb(0,153,0)">( tlx"padding:0px; margin:0px; color:rgb(51,153,51)">, tly"padding:0px; margin:0px; color:rgb(51,153,51)">, nw"padding:0px; margin:0px; color:rgb(51,153,51)">, nh"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 对图片 img 进行缩放,并存入到 TheImage 中  
  3.     cvResize"padding:0px; margin:0px; color:rgb(0,153,0)">( img"padding:0px; margin:0px; color:rgb(51,153,51)">, TheImage "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 重置 TheImage 的 ROI 准备读入下一幅图片  
  4.     cvResetImageROI"padding:0px; margin:0px; color:rgb(0,153,0)">( TheImage "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(0,153,0)">}"padding:0px; margin:0px; color:rgb(153,51,51)">void CmymfcDlg"padding:0px; margin:0px; color:rgb(51,153,51)">::"padding:0px; margin:0px; color:rgb(32,32,32)">ShowImage"padding:0px; margin:0px; color:rgb(0,153,0)">( IplImage"padding:0px; margin:0px; color:rgb(51,153,51)">* img"padding:0px; margin:0px; color:rgb(51,153,51)">, UINT ID "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(102,102,102)">// ID 是Picture Control控件的ID号{// 获得显示控件的 DC  
  5.     CDC"padding:0px; margin:0px; color:rgb(51,153,51)">* pDC "padding:0px; margin:0px; color:rgb(51,153,51)">= GetDlgItem"padding:0px; margin:0px; color:rgb(0,153,0)">( ID "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">->GetDC"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 获取 HDC(设备句柄) 来进行绘图操作  
  6.     HDC hDC "padding:0px; margin:0px; color:rgb(51,153,51)">= pDC "padding:0px; margin:0px; color:rgb(51,153,51)">->GetSafeHdc"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;               
  7.    
  8.     CRect rect"padding:0px; margin:0px; color:rgb(51,153,51)">;  
  9.     GetDlgItem"padding:0px; margin:0px; color:rgb(0,153,0)">(ID"padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">->GetClientRect"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(51,153,51)">&rect "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 求出图片控件的宽和高int rw = rect.right- rect.left;int rh = rect.bottom- rect.top;// 读取图片的宽和高int iw = img->width;int ih = img->height;// 使图片的显示位置正好在控件的正中int tx =(int)(rw - iw)/2;int ty =(int)(rh - ih)/2;  
  10.     SetRect"padding:0px; margin:0px; color:rgb(0,153,0)">( rect"padding:0px; margin:0px; color:rgb(51,153,51)">, tx"padding:0px; margin:0px; color:rgb(51,153,51)">, ty"padding:0px; margin:0px; color:rgb(51,153,51)">, tx"padding:0px; margin:0px; color:rgb(51,153,51)">+iw"padding:0px; margin:0px; color:rgb(51,153,51)">, ty"padding:0px; margin:0px; color:rgb(51,153,51)">+ih "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 复制图片  
  11.     CvvImage cimg"padding:0px; margin:0px; color:rgb(51,153,51)">;  
  12.     cimg."padding:0px; margin:0px; color:rgb(32,32,32)">CopyOf"padding:0px; margin:0px; color:rgb(0,153,0)">( img "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 将图片绘制到显示控件的指定区域内  
  13.     cimg."padding:0px; margin:0px; color:rgb(32,32,32)">DrawToHDC"padding:0px; margin:0px; color:rgb(0,153,0)">( hDC"padding:0px; margin:0px; color:rgb(51,153,51)">,"padding:0px; margin:0px; color:rgb(51,153,51)">&rect "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;     
  14.    
  15.     ReleaseDC"padding:0px; margin:0px; color:rgb(0,153,0)">( pDC "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(0,153,0)">}  
MFC—PictureControl控件使用,显示和处理图像
 CmymfcDlgIplImage img w  imgwidth h  imgheight max w  h w h scale  max  nw  wscale  nh  hscale  tlx nw  nhnw tly nw  nhnh
        cvSetImageROI TheImage cvRect tlx tly nw nh
        cvResize img TheImage 
        cvResetImageROI TheImage  CmymfcDlg IplImage img UINT ID 
        CDC pDC  GetDlgItem ID GetDC
        HDC hDC  pDC GetSafeHdc                          
 
        CRect rect
        GetDlgItemIDGetClientRectrect  rw  rect. rect. rh  rect. rect. iw  imgwidth ih  imgheight tx rw  iw ty rh  ih
        SetRect rect tx ty txiw tyih 
        CvvImage cimg
        cimg. img 
        cimg. hDCrect    
 
        ReleaseDC pDC 

函数 ResizeImage 是参考了学习笔记(5)中单窗口显示多幅图像的函数 cvShowMultiImages 修改而成的,函数ShowImage 则是参考了帖子《OpenCV如何把图像显示到MFCpicture控件上》的代码,另外下面几个帖子也可以参考:

1、《MFC picture control画框的问题》

2、《MFC picture control控件实现(隐藏)文字显示》

3、《MFCPictureControl中显示图片(jpg)遇到的问题》

4、《vc怎样在picturecontrol中显示jpg,jif,bmp格式图象》

5、《使用Picture Control显示BMP图片》

最后是要对读入的图像做简单的Canny边缘处理,为此,建立一个按钮 EdgeDetect,相应的响应代码如下:

  1. "padding:0px; margin:0px; color:rgb(153,51,51)">void CmymfcDlg"padding:0px; margin:0px; color:rgb(51,153,51)">::"padding:0px; margin:0px; color:rgb(32,32,32)">OnBnClickedEdgedetect"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(0,153,0)">{"padding:0px; margin:0px; color:rgb(102,102,102)">// TODO: Add your control notification handler code hereIplImage *gray =0,*edge =0;gray = cvCreateImage( cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U,1);edge = cvCreateImage( cvSize(IMAGE_WIDTH, IMAGE_HEIGHT), IPL_DEPTH_8U,1);cvCvtColor( TheImage, gray, CV_BGR2GRAY );cvCanny( gray, edge,30,100,3);cvCvtColor( edge, TheImage, CV_GRAY2BGR );      
  2.     ShowImage"padding:0px; margin:0px; color:rgb(0,153,0)">( TheImage"padding:0px; margin:0px; color:rgb(51,153,51)">, IDC_ShowImg "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(102,102,102)">// 调用显示图片函数  
  3.    
  4.     cvReleaseImage"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(51,153,51)">&gray "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;cvReleaseImage"padding:0px; margin:0px; color:rgb(0,153,0)">("padding:0px; margin:0px; color:rgb(51,153,51)">&edge "padding:0px; margin:0px; color:rgb(0,153,0)">)"padding:0px; margin:0px; color:rgb(51,153,51)">;"padding:0px; margin:0px; color:rgb(0,153,0)">}  
MFC—PictureControl控件使用,显示和处理图像
 CmymfcDlgIplImage gray edge gray  cvCreateImage cvSizeIMAGE_WIDTH IMAGE_HEIGHT IPL_DEPTH_8Uedge  cvCreateImage cvSizeIMAGE_WIDTH IMAGE_HEIGHT IPL_DEPTH_8UcvCvtColor TheImage gray CV_BGR2GRAY cvCanny gray edgecvCvtColor edge TheImage CV_GRAY2BGR     
    ShowImage TheImage IDC_ShowImg 
 
    cvReleaseImagegray cvReleaseImageedge 

这里主要是参考了《OpenCV教程-基础篇》P33的代码,不过并没有像书中那样创建新的 MyIplClass 类来进行图像的读取和处理操作。我觉得这篇文章中直接对 TheImage 进行处理可能不大妥当,按照教程那样新建一个类来处理才是比较稳妥吧。这里涉及到函数返回对象实例的过程、深拷贝和浅拷贝、拷贝构造、动态内存的使用、opencv相关接口的代码等方面,以后还要进一步深入学习和理解!

我们还可以在Resource View面板->mymfc(工程名称)->mymfc.rc->Version中修改程序的产品版本、名称等信息。

来看看程序生成后的效果:

Image:mfc_picctl_7.JPG

Image:mfc_picctl_8.JPG

Image:mfc_picctl_9.JPG

 

可以到这里下载源码: http://download.csdn.net/source/1779188

///

转载地址:http://blog.sina.com.cn/s/blog_49b1fa8701015o5t.html

 

方法1.先从最简单的开始,用picture 控件来实现.

步骤:

先在资源里Import一张图片,ID为IDB_BITMAP2

然后在对话框上添加一个picture控件,右键点击打开属性,

将type下拉框选择BITMAP,紧跟着下面就出现一个Image下拉框,

拉开就会看到所有已经载入好的图片,

选择你要的图片.运行程序即可看到.



方法2vc picture控件.通过背景图

同样如上,先载入一张图片,ID为IDB_BITMAP2

TestDlg.h中

CBrush m_brBk;//在public中定义 

TestDlg.cpp中

在初始化函数OnInitDialog()中加入:

BOOL CTestDlg::OnInitDialog()

{

                CDialog::OnInitDialog();

CBitmap bmp;

bmp.LoadBitmap(IDB_BITMAP2);

m_brBk.CreatePatternBrush(&bmp);

bmp.DeleteObject();

return TRUE;   // return TRUE   unless you set the focus to a control

}



在打开类向导,找到WM_CTLCOLOR消息,重载得对应函数OnCtlColor(),添加如下:

HBRUSH   CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 

{

                HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

                if (pWnd == this)

{

     return m_brBk;

}

        return hbr;

}

 

方法3 vc picture控件通过CBitmap,HBITMAP,直接用OnPaint()绘制

首先在CTestDlg类中声明一个变量:    CBitmap   m_bmp;

然后我们在对话框中加入一个picture 标签,名为IDC_STATIC1

然后:

BOOL CDisplayPic::OnInitDialog() 

{

        CDialog::OnInitDialog();

     if( m_bmp.m_hObject != NULL )//判断

         m_bmp.DeleteObject();

/载入图片

     HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 

         "c://aaa.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);

     if( hbmp == NULL ) 

         return FALSE;

///该断程序用来取得加载的BMP的信息

     m_bmp.Attach( hbmp );

     DIBSECTION ds;

     BITMAPINFOHEADER &bminfo = ds.dsBmih; 

     m_bmp.GetObject( sizeof(ds), &ds );

     int cx=bminfo.biWidth;   //得到图像宽度

     int cy=bminfo.biHeight; //得到图像高度

     ///

/得到了图像的宽度和高度后,我们就可以对图像大小进行适应,即调整控件的大小,让它正好显示一张图片///

     CRect rect;

     GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);

     ScreenToClient(&rect);

     GetDlgItem(IDC_STATIC1)->MoveWindow(rect.left,rect.top,cx,cy,true);//调整大小



     return TRUE;   // return TRUE unless you set the focus to a control

                   // EXCEPTION: OCX Property Pages should return FALSE

}

图片加载成功了,标签大小也适应了,下面就是绘制绘制图像了,打开类向导,重载WM_PAINT消息

void CDisplayPic::OnPaint() 

{

//以下三种情况任选一种会是不同效果(只能一种存在)///

     //CPaintDC dc(this);       //若用此句,得到的是对话框的DC,图片将被绘制在对话框上.

     CPaintDC dc(GetDlgItem(IDC_STATIC1)); //用此句,得到picture控件的DC,图像将被绘制在控件上  

     //   CDC dc;

     //   dc.m_hDC=::GetDC(NULL);   //若用此两句,得到的是屏幕的DC,图片将被绘制在屏幕上///

     CRect rcclient;

     GetDlgItem(IDC_STATIC1)->GetClientRect(&rcclient);

     CDC memdc;

     memdc.CreateCompatibleDC(&dc);  

     CBitmap bitmap;

     bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());

     memdc.SelectObject( &bitmap );



     CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);



     CDC maskdc;

     maskdc.CreateCompatibleDC(&dc);

     CBitmap maskbitmap;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尔雅慕客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值