OpenCV2.2版本以上显示图片到MFC 的picture control中
2017-02-28 10:37
791 查看
OpenCV 2.2 以及后面的版本取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致无法调用里面的显示函数来将图片显示到 MFC 的 Picture Control 控件中。为此,网上很多人表示只要将这两个文件人为的添加到自己的工程里面就解决问题了,网上有这两个文件的源代码,但是这麻烦不说,还会导致一些奇奇怪怪的报错,自己在尝试的过程中遇到了很多问题,所以在了解了一些GDI绘图之后结合网上的代码写了如下的函数,只需调用就可以将OpenCV的图片显示在picture control中了,初步测试效率跟原来两个文件差不多,如果有大神请帮我继续完善这份代码!
本人使用的OpenCV版本为OpenCV2.4.9,在VS2012中配置好之后,在文件头部添加如下一行代码:
#define WIDTHBYTES(bits) (((bits)+31)/32*4) ; //用于使图像宽度所占字节数为4byte的倍数
首先在对话框类中声明函数:void ShowImage( IplImage * img, unsigned int ID) ,其中参数一为OpenCV的图像数据结构类,参数二为picture control的ID
定义该函数如下:
void CImageRetrievalSystemDlg::ShowImage(IplImage * img, unsigned int ID) //ImageRetrievalSystemDlg 为对话框类名
{
BYTE *g_pBits;
HDC g_hMemDC;
HBITMAP g_hBmp, g_hOldBmp;
CDC *pDC;
CStatic *pic;
int width, height;
CRect rect;
pDC = GetDlgItem(ID)->GetDC();
pic = (CStatic*)GetDlgItem(ID);
pic->GetClientRect(&rect);
width = rect.Width();
height = rect.Height();
g_hMemDC = ::CreateCompatibleDC(pDC->m_hDC);//创建兼容DC
BYTE bmibuf[sizeof(BITMAPINFO)+256 * sizeof(RGBQUAD)];
memset(bmibuf, 0, sizeof(bmibuf));
BITMAPINFO *pbmi = (BITMAPINFO*)bmibuf;
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = img->width;
pbmi->bmiHeader.biHeight = img->height;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = 24;
pbmi->bmiHeader.biCompression = BI_RGB;
g_hBmp = ::CreateDIBSection(g_hMemDC, pbmi, DIB_RGB_COLORS, (void**)&g_pBits, 0, 0);//创建应用程序可以直接写入的、与设备无关的位图(DIB)
g_hOldBmp = (HBITMAP)::SelectObject(g_hMemDC, g_hBmp);//复原兼容DC数据
BitBlt(g_hMemDC, 0, 0, width, height, pDC->m_hDC, 0, 0, SRCCOPY);
//修改图像内容:g_pBits
int l_width = WIDTHBYTES(img->width* pbmi->bmiHeader.biBitCount);
for (int row = 0; row < img->height; row++)
memcpy(&g_pBits[row*l_width], &img->imageData[ (img->height - row - 1)*l_width], l_width);
TransparentBlt(pDC->m_hDC, 0, 0, width, height, g_hMemDC, 0, 0, img->width, img->height, RGB(0, 0, 0));
SelectObject(g_hMemDC, g_hOldBmp);
//释放内存资源
ReleaseDC(pDC);
DeleteDC(g_hMemDC);
DeleteObject(pic);
DeleteObject(g_hBmp);
DeleteObject(g_hOldBmp);
}
然后在按钮的消息响应函数中添加如下代码:
void CImageRetrievalSystemDlg::OnBnClickedButtonQuery()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(true,_T("*.jpg"),NULL,OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,_T("image file(*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|All Files(*.*)|*.*|"),NULL);
dlg.m_ofn.lpstrTitle=_T("open Image");
if(dlg.DoModal()!=IDOK)
return;
CString query_path=dlg.GetPathName();
query_path.Replace(_T("//"),_T("////"));
IplImage *qimg =cvLoadImage((CT2CA)query_path,1);
if(qimg!=NULL)
{
ShowImage(qimg,IDC_STATIC_QUERY);// IDC_STATIC_QUERY为picture control ID
}
}
最后运行程序结果如下:
点击按钮“查询图像”,载入任意一张图片:
自己尝试做的一个小demo,记录下来,为初学者提供一个方向,也为自己梳理下思路。
本人使用的OpenCV版本为OpenCV2.4.9,在VS2012中配置好之后,在文件头部添加如下一行代码:
#define WIDTHBYTES(bits) (((bits)+31)/32*4) ; //用于使图像宽度所占字节数为4byte的倍数
首先在对话框类中声明函数:void ShowImage( IplImage * img, unsigned int ID) ,其中参数一为OpenCV的图像数据结构类,参数二为picture control的ID
定义该函数如下:
void CImageRetrievalSystemDlg::ShowImage(IplImage * img, unsigned int ID) //ImageRetrievalSystemDlg 为对话框类名
{
BYTE *g_pBits;
HDC g_hMemDC;
HBITMAP g_hBmp, g_hOldBmp;
CDC *pDC;
CStatic *pic;
int width, height;
CRect rect;
pDC = GetDlgItem(ID)->GetDC();
pic = (CStatic*)GetDlgItem(ID);
pic->GetClientRect(&rect);
width = rect.Width();
height = rect.Height();
g_hMemDC = ::CreateCompatibleDC(pDC->m_hDC);//创建兼容DC
BYTE bmibuf[sizeof(BITMAPINFO)+256 * sizeof(RGBQUAD)];
memset(bmibuf, 0, sizeof(bmibuf));
BITMAPINFO *pbmi = (BITMAPINFO*)bmibuf;
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = img->width;
pbmi->bmiHeader.biHeight = img->height;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = 24;
pbmi->bmiHeader.biCompression = BI_RGB;
g_hBmp = ::CreateDIBSection(g_hMemDC, pbmi, DIB_RGB_COLORS, (void**)&g_pBits, 0, 0);//创建应用程序可以直接写入的、与设备无关的位图(DIB)
g_hOldBmp = (HBITMAP)::SelectObject(g_hMemDC, g_hBmp);//复原兼容DC数据
BitBlt(g_hMemDC, 0, 0, width, height, pDC->m_hDC, 0, 0, SRCCOPY);
//修改图像内容:g_pBits
int l_width = WIDTHBYTES(img->width* pbmi->bmiHeader.biBitCount);
for (int row = 0; row < img->height; row++)
memcpy(&g_pBits[row*l_width], &img->imageData[ (img->height - row - 1)*l_width], l_width);
TransparentBlt(pDC->m_hDC, 0, 0, width, height, g_hMemDC, 0, 0, img->width, img->height, RGB(0, 0, 0));
SelectObject(g_hMemDC, g_hOldBmp);
//释放内存资源
ReleaseDC(pDC);
DeleteDC(g_hMemDC);
DeleteObject(pic);
DeleteObject(g_hBmp);
DeleteObject(g_hOldBmp);
}
然后在按钮的消息响应函数中添加如下代码:
void CImageRetrievalSystemDlg::OnBnClickedButtonQuery()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(true,_T("*.jpg"),NULL,OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,_T("image file(*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|All Files(*.*)|*.*|"),NULL);
dlg.m_ofn.lpstrTitle=_T("open Image");
if(dlg.DoModal()!=IDOK)
return;
CString query_path=dlg.GetPathName();
query_path.Replace(_T("//"),_T("////"));
IplImage *qimg =cvLoadImage((CT2CA)query_path,1);
if(qimg!=NULL)
{
ShowImage(qimg,IDC_STATIC_QUERY);// IDC_STATIC_QUERY为picture control ID
}
}
最后运行程序结果如下:
点击按钮“查询图像”,载入任意一张图片:
自己尝试做的一个小demo,记录下来,为初学者提供一个方向,也为自己梳理下思路。
相关文章推荐
- OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中
- OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中
- OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中
- opencv2.2 MFC picture控件中显示图片
- opencv2.2 MFC picture控件中显示图片
- OpenCV 2.2版本号以上显示图片到 MFC 的 Picture Control 控件中
- Opencv在MFC客户端的Picture控件上显示图片
- 【C++ MFC+opencv】打开文件夹中的图片并在picture控件中显示
- MFC picture control 显示不同格式图片
- MFC Picture Control显示OpenCV图像
- VS2010-MFC:MFC PictureControl控件上自适应显示图片,分图片失真或者图片不失真两种
- MFC picture control控件不失真自适应图片显示
- opencv1.0 mfc显示picture控件图片
- MFC Picture Control显示图片
- MFC Picture Control控件显示图片
- MFC picture control控件不失真自适应图片显示
- 关于OpenCV3版本与MFC配合显示图片
- 在MFC中使用opencv2以上版本对图像进行显示
- mfc- Picture control显示图片
- MFC picture control控件不失真自适应图片显示