OpenCV4.1 显示图像到MFC Pictrue控件

新版本的opencv取消了CvvImage,然而就不支持在MFC中显示了。这里介绍一种新的显示图像的方法。

环境:OpenCV4.1 +MCF 对话框 +Picture控件

方法一:直接将Mat显示在Picture窗体上

显示函数定义如下,

// MFC上Picture Control控件显示图像

// src 待显示的图像 (OpenCV库Mat对象结构)

// hwnd MFC显示图像的窗口句柄

void CXXXDlg::ShowImage(Mat& imgSrc, HWND hwnd) {

         HDC hdc = ::GetDC(hwnd);

         CRect rect;

         //获取图片控件矩形框

         GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetClientRect(&rect);

         //缩放Mat,以适应图片控件大小

         cv::resize(imgSrc, imgSrc, cv::Size(rect.Width(), rect.Height()));

         //cv::resize(imgSrc, imgSrc, cv::Size(300, 300));

         // 转换格式 ,便于获取BITMAPINFO

         switch (imgSrc.channels())

         {

         case 1:

                   cv::cvtColor(imgSrc, imgSrc, COLOR_GRAY2BGRA); // GRAY单通道

                   break;

         case 3:

                   cv::cvtColor(imgSrc, imgSrc, COLOR_BGR2BGRA);  // BGR三通道

                   break;

         default:

                   break;

         }

         // 计算一个像素多少个字节

         int pixelBytes = imgSrc.channels()*(imgSrc.depth() + 1);

         // 制作bitmapinfo(数据头)

         BITMAPINFO bitInfo;

         bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;

         bitInfo.bmiHeader.biWidth = imgSrc.cols;

         bitInfo.bmiHeader.biHeight = -imgSrc.rows;   //注意"-"号(正数时倒着绘制)

         bitInfo.bmiHeader.biPlanes = 1;

         bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

         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;

         CDC *pDC = GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetDC();  //获取图片控件DC

         //绘图

         ::StretchDIBits(

                   pDC->GetSafeHdc(),

                   0, 0, rect.Width(), rect.Height(),

                   0, 0, imgSrc.cols, imgSrc.rows,

                   imgSrc.data,

                   &bitInfo,

                   DIB_RGB_COLORS,

                   SRCCOPY

         );

         ReleaseDC(pDC);  //释放DC

}

函数调用方法:

HWND hwnd = GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetSafeHwnd();
// 获取显示的图像
Mat img = imread("D:/images/11111.jpg");
// 调用显示函数
ShowImage(img, hwnd);

方法二:用Mat转CImage的方式,然后在Pictrue控件上绘制CImage

Mat转CImage

void CXXXDlg::MatToCImage(Mat &mat, CImage &cImage)

{

         //create new CImage 
         int width = mat.cols;
         int height = mat.rows;
         int channels = mat.channels();
         cImage.Destroy(); //clear 
         cImage.Create(width, height, 8 * channels); //默认图像像素单通道占用1个字节 

         //copy values 
         uchar* ps;
         uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer 
         int step = cImage.GetPitch();
         for (int i = 0; i < height; ++i)

         {
                   ps = (mat.ptr<uchar>(i));
                   for (int j = 0; j < width; ++j)
                   {
                            if (channels == 1) //gray 

                            {
                                     *(pimg + i * step + j) = ps[j];
                            }
                            else if (channels == 3) //color 
                            {
                                     for (int k = 0; k < 3; ++k)
                                     {
                                               *(pimg + i * step + j * 3 + k) = ps[j * 3 + k];
                                     }
                            }
                   }
         }
}

函数调用示例:


void CXXXDlg::ShowMethord4()

{

         int cxl, cyl;

         Mat rgbImageL1 = imread("D:/images/11111.jpg");//opencv图片

         CImage  rgbImageL2;

         CRect   rectl, pic_rectl;

         int widthl, heightl;

         //改变图片大小适应picture控件

         GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetClientRect(&pic_rectl);

         widthl = pic_rectl.right;

         heightl = pic_rectl.bottom;

         resize(rgbImageL1, rgbImageL1, Size(widthl, heightl));

         MatToCImage(rgbImageL1, rgbImageL2);//OpenCV中Mat对象转MFC的CImage类的函数

         //获取图片的宽 高度 

         cxl = rgbImageL2.GetWidth();

         cyl = rgbImageL2.GetHeight();

         //获取Picture Control控件的大小 

         GetDlgItem(IDC_STATIC_SHOWIMAGE)->GetWindowRect(&rectl);

         //将客户区选中到控件表示的矩形区域内 

         ScreenToClient(&rectl);

         //窗口移动到控件表示的区域 

         GetDlgItem(IDC_STATIC_SHOWIMAGE)->MoveWindow(rectl.left, rectl.top, cxl, cyl, TRUE);

         CWnd *pWnd = NULL;

         pWnd = GetDlgItem(IDC_STATIC_SHOWIMAGE);//获取控件句柄 

         pWnd->GetClientRect(&rectl);//获取句柄指向控件区域的大小 

         CDC *pDc = NULL;

         pDc = pWnd->GetDC();//获取picture的DC 

         rgbImageL2.Draw(pDc->m_hDC, rectl);//将图片绘制到picture表示的区域内 

         ReleaseDC(pDc);

}

 

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法哥2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值