void CXXXDlg::DrawOpenCvMat(Mat& img, UINT nID)
{
Mat imgTmp;
CRect rect;
GetDlgItem(nID)->GetClientRect(&rect);
// 获取控件大小
int nWidth = rect.Width();
int nHeight = rect.Height();
resize(img, imgTmp, Size(nWidth, nHeight));// 缩放Mat并备份
//resize(img, imgTmp, Size(), 0.5, 0.5, INTER_LINEAR);//0.5:把原图w h两个方向缩小一倍
// 转格式
switch (imgTmp.channels())
{
case 1:
cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道
break;
case 3:
cvtColor(imgTmp, imgTmp, CV_BGR2BGRA); // BGR三通道
break;
default:
break;
}
int pixelBytes = imgTmp.channels()*(imgTmp.depth() + 1); // 计算一个像素多少个字节
// 读取位图文件中的头信息
// [制作bitmapinfo(数据头)]
BITMAPINFO bitInfo;
bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;
bitInfo.bmiHeader.biWidth = imgTmp.cols;
bitInfo.bmiHeader.biHeight = -imgTmp.rows;//必须为负,否则图像是翻转显示
bitInfo.bmiHeader.biPlanes = 1;
bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);//必须,初始化bitmapinfo.bmiHeader中的第一个参数
bitInfo.bmiHeader.biCompression = BI_RGB;
bitInfo.bmiHeader.biClrImportant = 0;
bitInfo.bmiHeader.biClrUsed = 0;
bitInfo.bmiHeader.biSizeImage = 0;
bitInfo.bmiHeader.biXPelsPerMeter = 0;
bitInfo.bmiHeader.biYPelsPerMeter = 0;
// Mat.data + bitmap数据头 -> MFC
CDC *pDC = GetDlgItem(nID)->GetDC();
//显示
StretchDIBits(
pDC->GetSafeHdc(),
0, 0, rect.Width(), rect.Height(),
0, 0, rect.Width(), rect.Height(),
imgTmp.data,
&bitInfo,
DIB_RGB_COLORS,
SRCCOPY
);
//StretchDIBits()将DIB中矩形区域内像素使用的颜色数据拷贝到指定的目标矩形中。
//如果目标矩形比源矩形大小要大,那么函数对颜色数据的行和列进行拉伸,以与目标矩形匹配。
//如果目标矩形大小要比源矩形小,那么该函数通过使用指定的光栅操作对行列进行压缩。
ReleaseDC(pDC);
}
在MFC需要显示图片的时候调用即可,如在按钮中调用:
void CXXXDlg::OnBnClickedBtnShow()
{
FindContours* pf = new FindContours(); //自定义处理图片的类
cv::Mat img;
pf->TestMain(img); //获得处理后的图片,保存在img中
//显示img
DrawOpenCvMat(img, IDC_STATIC_IMG);
}