目前网络上,使用opencv和MFC显示图片的方法大致分为以下几种:
1:将opencv的显示对话框嵌入到MFC窗口
2:使用CvvImage类显示图片
3:自己写代码将Mat结构转换为CImage结构
方法1过于取巧,缺陷明显。方法2需要将opencv自2.x起就弃用的CvvImage类导入工程。方法3比较复杂,看他们的代码好像还要循环拷贝图像数据。
今天给大家介绍另外一种方法,是用google在国外网站上搜到的,整理了一下供大家参考。
opencv的环境配置大家自己搜下就行了。IDC_STATIC_IMAGE是Picture Control的控件ID
void CCircleRecognitionDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
using namespace cv;
CRect rect;
int width, height;
BITMAPINFO bitmapInfo;
BITMAPINFOHEADER* bmiHeader;
Mat image = imread("D:\\image\\Debug\\01.bmp");
width = image.cols;
height = image.rows;
if (width % 4)
width = (width + 3) / 4 * 4;
cv::Size winSize(width, height);
cv::Mat cvImgTmp(winSize, CV_8UC3);
if (image.size() != winSize)
cv::resize(image, cvImgTmp, winSize);
else
cvImgTmp = image.clone();
GetDlgItem(IDC_STATIC_IMAGE)->GetClientRect(&rect);
bmiHeader = &bitmapInfo.bmiHeader;
bmiHeader->biSize = sizeof(BITMAPINFOHEADER);
bmiHeader->biWidth = cvImgTmp.cols;
bmiHeader->biHeight = -cvImgTmp.rows;
bmiHeader->biPlanes = 1;
bmiHeader->biBitCount = 24;
bmiHeader->biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = 0;
bmiHeader->biXPelsPerMeter = GetSystemMetrics(SM_CXSCREEN);
bmiHeader->biYPelsPerMeter = GetSystemMetrics(SM_CYSCREEN);
bmiHeader->biClrUsed = 0;
bmiHeader->biClrImportant = 0;
StretchDIBits(GetDlgItem(IDC_STATIC_IMAGE)->GetDC()->GetSafeHdc()
, 0, 0, std::min(rect.Width(), rect.Height()), std::min(rect.Width(), rect.Height())
, 0, 0, cvImgTmp.cols, cvImgTmp.rows,
cvImgTmp.data, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
}
}