如何让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指针就可以了。
下载示例程序地址: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指针就可以了。
相关文章推荐
- 如何让OpenCV的图片显示在MFC窗口上
- 如何让OpenCV的图片显示在MFC窗口上
- OPENCV如何把图片显示到MFC的picture控件上
- 如何在MFC窗口显示BMP和JPG图片
- 【OpenCV2】MFC中用OPENCV如何将图片显示在指定位置?
- 如何将OpenCV中的IplImage显示在MFC的窗口中
- MFC中用OPENCV如何将图片显示在指定位置?
- [转]如何将OpenCV中的IplImage显示在MFC的窗口中
- 基于MFC单文档下调用opencv库并将图片效果显示在单文档窗口
- 如何在MFC窗口显示BMP和JPG图片
- MFC使用OpenCV在文档窗口中显示图像(支持多图片格式)
- 如何利用opencv在一个窗口显示多张图片
- 【OpenCV2】MFC中用OPENCV如何将图片显示在指定位置
- 如何在MFC窗口显示BMP和JPG图片
- login控件 登陆图片居右显示 登陆窗口不管分辨率,窗口如何变化,一直居中显示
- Opencv显示图片的窗口大小
- OpenCV+MFC快速应用:如何在MFC中显示Mat图像
- MFC下应用opencv(1):显示图片
- OpenCV如何把图像显示到MFC的picture控件上
- 利用opencv将两张图像在同一窗口上显示,并在图片上显示文字