原文地址:http://blog.csdn.net/u012250337/article/details/51601905
(1)使用opencv的CvvImage类
该方法比较简单,但是opencv2.x以上版本已经不支持CvvImage类,不过可以在网上下载该类的头文件和源文件,添加到工程里就可以使用了。
- void CXXXDlg::DrawIplImage2MFC(IplImage* img, unsigned int id)
- {
- CDC* pDC = GetDlgItem(id)->GetDC();
- HDC hDC = pDC->GetSafeHdc();
- CvvImage cimg;
- cimg.CopyOf( img );
- CRect rect;
- GetDlgItem(id)->GetClientRect(&rect);
- cimg.DrawToHDC(hDC, &rect);
- ReleaseDC( pDC );
- }
函数参数中id是控件ID,比如IDC_STATIC(下同)。
(2)使用MFC的绘图函数
该方法利用MFC的绘图函数,将opencv图像数据先copy到缓冲去然后在控件上显示出来。
- void CXXXDlg::DrawIplImage2MFC(IplImage* img, unsigned int id)
- {
- 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);
- 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);
- g_hOldBmp = (HBITMAP)::SelectObject(g_hMemDC, g_hBmp);
- BitBlt(g_hMemDC, 0, 0, width, height, pDC->m_hDC, 0, 0, SRCCOPY);
- 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);
- DeleteDC(g_hMemDC);
- DeleteObject(pic);
- DeleteObject(g_hBmp);
- DeleteObject(g_hOldBmp);
- }
(3)链接opencv窗口和MFC控件
该方法是将opencv的显示窗口与MFC的控件链接起来,效果是opencv的窗口恰好覆盖在控件上。
- bool CXXXDlg::attachWindow(string &pic,const char* name,int ID)
- {
- pic=string(name);
- cv::namedWindow(pic, 1);
- HWND hWnd = (HWND) cvGetWindowHandle(name);
- HWND hParent = ::GetParent(hWnd);
- ::SetParent(hWnd, GetDlgItem(ID)->m_hWnd);
- ::ShowWindow(hParent, SW_HIDE);
- return true;
- }
- bool CXXXDlg::showImage(string pic,int id,cv::Mat mat)
- {
- CRect rect;
- GetDlgItem(id)->GetClientRect(&rect);
- cv::resize(mat,mat,cv::Size(rect.Width(),rect.Height()),CV_INTER_CUBIC);
- imshow(pic,mat);
- return true;
- }
使用方法是先链接opencv窗口的标识符和控件ID
- string pic;
- attachWindow(pic,"win",IDC_PIC);
然后在需要显示图像的地方调用showImage
- Mat mat=imread("1.jpg");
- showImage(pic,IDC_PIC,mat);