MFC的picture控件加载并显示Mat图片

18 篇文章 1 订阅
7 篇文章 0 订阅

前期准备工作:

将编译好的opencv库添加到项目中,include、lib、bin文件夹放置好。需要区分是debug还是release版本,以及32位还是64位。以上工作准备好之后,就可以使用下面代码进行显示图片了。

1、编译opencv,    ----->    配置项目   

2、RGB图片显示,需要注意4字节对齐的问题。Mat不是4字节对齐,但是bitmap是4字节对齐问题。所以,就有一个转化。

3、加载图片,需要注意Unicode宽字节与多字节转换的问题。多字节与宽字节转换

1、显示当前项目路径下的一张图片

void CMyDlg::OnBnClickedLoadImg()
{
    // 调试时,图片放在*.sln目录下。执行时,放在对应的*.exe目录下
    cv::Mat mat = cv::imread("1.png");
    if(mat.empty())    return;// 图片不存在,则返回

    CWnd *pWin = GetDlgItem(IDC_IMG);// picture控件IDC_IMG, 获取窗口句柄
    CRect rect;
    pWin->GetClientRect(&rect);// 获取窗口大小
    int width = rect.right;
    int height = rect.botton;
    CDC* dc = pWin->GetDC(); // 获取picture控件的 设备绘图指针
    HDC hdc = dc->GetSafeHdc();  //获取该DC指针的 句柄(一般用于api函数使用)

    // 显示图像,调整图像尺寸
    cv::Mat out;
    // 由于picture与图片不符,所以需要用opencv函数调整图片大小
    cv::resize(mat, out, cv::Size(width , height));

    // 4字节对齐。解决图像灰掉并倾斜的问题。如果不是4字节的话,图片会倾斜+变灰色
    if(width%4 != 0)
	    width = width + (4 - width%4);// 只能补齐差的几位,不能删除。

    // 位图信息设置
    BITMAPINFO bmi = {0};// C++11 才可以直接置0. 否则需要用memset函数置0
    // memset(&bim, 0, sizeof(BITMAPINFOHEADER)); // 置0
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);// 初始化空间大小
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height;// 位图的显示与opencv的y轴正好相反
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;// 压缩方式 RGB

    // 完成显示(会把图像拉宽或高)
    SetDIBitsToDevice(
		hdc,	// 句柄
		0,0,	// 起始位置
		width,height,// 显示宽高
		0,0,0,			// 原图位置
		height,		// 显示行数
		outImg.data,// 图
		&bmi,		// 转到bmi
		DIB_RGB_COLORS);

    // 显示完一幅图,需要释放dc
    ReleaseDC(dc);
}

2、打开文件,找一张图片进行显示

void CMyDlg::OnBnClickedOpenImg()
{
    // 文件打开窗口
    CFileDlg fdlg(TRUE, NULL, NULL, NULL, L"打开图片(jpg png bmp gif)|*.jpg;*.png;*.bmp;*.gif|", this);
    if(fdlg.DoModal() != IDOK)    return;
    
    // 获取到文件名,由于是Unicode编码,需要转换
    USES_CONVERSION;// W2A之前,必须要有这句话
    char* c = W2A(fdlg.GetPathName().GetBuffer());// 然后才可以用W2A
    cv::Mat mat = cv::imread(c);// 加载图片

    if(mat.empty())    return;

    CWnd *pWin = GetDlgItem(IDC_IMG);
    CRect rect;
    pWin->GetClientRect(&rect);
    int width = rect.right;
    int height = rect.botton;
    CDC* dc = pWin->GetDC();
    HDC hdc = dc->GetSafeHdc();

    // 显示图像,调整图像尺寸
    cv::Mat out;
    cv::resize(mat, out, cv::Size(width , height));

    // 4字节对齐。解决图像灰掉并倾斜的问题
    if(width%4 != 0)
	    width = width + (4 - width%4);

    // 位图信息设置
    BITMAPINFO bmi = {0};
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;
   
    // 完成显示(会把图像拉宽或高)
    SetDIBitsToDevice(
		hdc,	// 句柄
		0,0,	// 起始位置
		width,height,// 显示宽高
		0,0,0,			// 原图位置
		height,		// 显示行数
		outImg.data,// 图
		&bmi,		// 转到bmi
		DIB_RGB_COLORS);

    // 释放
    ReleaseDC(dc);
}

MFC布局如下: 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值