您的位置:首页 > 运维架构

如何让OpenCV的图片显示在MFC窗口上

2010-11-30 16:21 453 查看
from: http://peng-jun.blog.163.com/blog/static/215628142009325104710656/

下载示例程序地址:http://download.csdn.net/source/1247134

 

以前就想过如何让OpenCV的图片不是显示在一个由cvNamedWindow生成的窗体,而是显示在MFC的窗体上。可是,没有在OpenCV的函数库中找到相应的函数,也就没有在往下多想。今天,又有一个同学问起来这件事,于是想到了不如自己写一个函数来实现这样的功能不就OK了。结果,就出现了下面的函数:

void ShowMFC(IplImage *img, CDC *pDC)
{
 DWORD height=img->height;
 DWORD width=img->width;
 DWORD lineBytes=(width*8+31)/32*4;
 DWORD lineBytes24=(width*24+31)/32*4;

 BYTE *temp=new BYTE[img->height*lineBytes24];
 if(!temp) return;
 memset(temp,0,height*lineBytes24);

 WORD bitCount;
 if(img->nChannels==1)
 {
  bitCount=8;
 }
 else if(img->nChannels==3)
 {
  bitCount=24;
 }
 else
 {
  delete[] temp;
  temp=NULL;
  return;
 }

 if(bitCount==8)
 {
  for(int i=0;i<img->height;i++)
  {
   for(int j=0,n=0;j<img->width*3;j++,n++)
   {
    *(temp+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->imageData+img->widthStep*i))
;
    j++;
    *(temp+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->imageData+img->widthStep*i))
;
    j++;
    *(temp+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->imageData+img->widthStep*i))
;
   }
  }
 }
 else
 {
  for(int i=0;i<img->height;i++)
  {
   for(int j=0,n=0;j<img->width*3;j++,n++)
   {
    *(temp+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->imageData+img->widthStep*i))[3*n];
    j++;
    *(temp+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->imageData+img->widthStep*i))[3*n+1];
    j++;
    *(temp+lineBytes24*(height-1-i)+j)=(BYTE)((uchar*)(img->imageData+img->widthStep*i))[3*n+2];
   }
  }
 }

 BITMAPINFO bi;
//  for(int n=0;n<256;n++)
//  {
//   bi.bmiColors
.rgbBlue=(BYTE)n;
//   bi.bmiColors
.rgbGreen=(BYTE)n;
//   bi.bmiColors
.rgbRed=(BYTE)n;
//   bi.bmiColors
.rgbReserved=(BYTE)0;
//  }
 bi.bmiHeader.biBitCount=24;
 bi.bmiHeader.biClrImportant=0;
 bi.bmiHeader.biClrUsed=0;
 bi.bmiHeader.biCompression=0L;
 bi.bmiHeader.biHeight=height;
 bi.bmiHeader.biPlanes=1;
 bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
 bi.bmiHeader.biSizeImage=height*lineBytes;
 bi.bmiHeader.biWidth=width;
 bi.bmiHeader.biXPelsPerMeter=0;
 bi.bmiHeader.biYPelsPerMeter=0;
 
 StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,height,temp,(BITMAPINFO*)&bi,DIB_RGB_COLORS,SRCCOPY);
 
 delete[] temp;
 temp=NULL;
}

值得注意的是,上面注释的代码部分不知道为什么一旦运行就会改变IplImage结构体的值,所以只能不运行那段程序。也就是要把OpenCV读入的图片全部的转换为24位位图的格式,这样就不需要去改变BITMAPINFO结构体中bmiColors的内容。这点从程序中也能看出来。

可以把上面的函数作为一个全局函数,然后,下面是调用上面函数的程序:

void CTestShowInMFCWindowDlg::OnBtnOpen()
{
 // TODO: Add your control notification handler code here
 char szFilter[]="BMP files(*.bmp)|*.bmp|JPG files(*.jpg)|*.jpg|All files(*.*)|*.*||";
 CFileDialog ofd(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
 if(ofd.DoModal()!=IDOK) return;

 IplImage *src=cvLoadImage(ofd.GetPathName(),CV_LOAD_IMAGE_ANYCOLOR);
 if(!src) return;
 
 RedrawWindow();
 ShowMFC(src,GetDC());
}

 

因为ShowMFC函数只要传入要显示的OpenCV的结构体IplImage*和一个要显示的CDC指针就可以了。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc byte colors null delete image