1. 配置opencv
    在操作之前,我们应该先进行opencv的配置,如果不提前配置好,当我们在用Opencv库里的函数是会报错。关于这点,网上已经有很多配置的博客供大家参考,我就不赘述了,这里放上我配置时看的那篇博客,希望能帮到大家https://blog.csdn.net/shuiyixin/article/details/105998661;
    (因为我配置的时候,无论如何都做不到一次配置一劳永逸,应该是我的方法问题。所以如果你也是这样,建议将配置好的信息保存下来,生成配置文件,下次使用的时候就可以直接在“属性”界面,DebugX64和ReleaseX64下导入就可以用了,也挺方便的)
  2. 具体操作
    打开VS2019,创建新项目,选择MFC应用,基于对话框,确定;
    (oh,天哪,请忽略我这糟糕的用户名,只怪我当年年少轻狂啊555)首先一定是合理布置空间按钮这些!记得添加图片控件的时候记得type设置为Rectangle(我是这样设置了才会显示图片,好像也不都是必须要这么设置)
    头文件及变量准备(在AAAADlg.cpp中):
#include "pch.h"
#include "framework.h"
#include "AAAA.h"
#include "AAAADlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
int judge = -1;
BITMAPINFO bitInfo;
CRect rect;
char path1[100];

在AAAADlg.h中添加如下头文件:

#include <iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

#include<string>

并添加成员函数show_image:

void show_image(Mat& imgSrc, HWND hwnd, int judge);

双击“导入图片”控件按钮,进入响应代码编辑加入如下代码:

Mat src;
	CString filter;
	CString path;
	filter = "All Files (*.*)|*.*|JPGtu图片(*.jpg)|*.jpg|BMP图像(*.bmp)|*.bmp|PNG图片(*.png)|*.png||";
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter);
	if (dlg.DoModal() != IDOK)
	{
		MessageBoxA(NULL, "does not chose image", "出错!", IDOK);
		return;
	}
	path = dlg.GetPathName();
	path.Replace(_T("\\"), _T("\\\\"));//转移字符的转换 
	memset(path1, 0, sizeof(path1));
	int k = path.GetAllocLength();
	for (int i = 0; path[i] != 0; i++)
	{
		path1[i] = path[i];
	}

	src = imread(path1);
	MessageBoxA(NULL, path1, "图片路径", IDOK);
	if (!src.data)
	{
		MessageBoxA(NULL, "could not load picture", "出错!", IDOK);
		return;
	}
	HWND hwnd = GetDlgItem(IDC_SHOWIMAGE)->GetSafeHwnd();
	show_image(src, hwnd, judge);

这里读取图片路径的时候发生了一点小插曲,因为我个性的用户名是中文的,所以读取图片路径老是不对,因为我图片放在了桌面上;查半天怎么改用户名发现好麻烦,最后折磨我两天之后,我突然发现,图片为什么非要放在桌面(C盘)呢,然后我放到D盘就解决问题了(暴风哭泣)我真傻 真的…

双击“反转图片”按钮,添加如下代码:

	Mat src;
	src = imread(path1);
	HWND hwnd = GetDlgItem(IDC_SHOWIMAGE)->GetSafeHwnd();
	judge *= (-1);
	show_image(src, hwnd, judge);

双击“镜像翻转”按钮,添加如下代码:

Mat src;
	Mat dst;
	src = imread(path1);
	HWND hwnd = GetDlgItem(IDC_SHOWIMAGE)->GetSafeHwnd();
	flip(src, dst, 1);
	show_image(dst, hwnd, judge);

双击“保存图片”按钮,添加如下代码:

TCHAR szFilter[] = _T("JPG图片(*.jpg)|*.jpg|BMP图片(*.bmp)|*.bmp|PNG图片(*.png)|*.png|JPEG图片(*.jpeg)|*.jpeg|DIB图片(*dib)|*.dib|PBM图片(*.pbm)|*.pbm||");
	// 构造保存文件对话框 
	CFileDialog fileDlg(FALSE, _T("jpg"), _T("New"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this);
	CString strFilePath;
	// 显示保存文件对话框 
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“保存”按钮,则将选择的文件路径显示到编辑框里 
		strFilePath = fileDlg.GetPathName();

	}
	vector<int> compression_params;
	std::string STDStr(CW2A(strFilePath.GetString()));
	Mat src;
	src = imread(path1);
	imwrite(STDStr, src, compression_params);

AAAADlg.cpp中show_image函数实现:

HDC hdc = ::GetDC(hwnd);


	//获取图片控件矩形框

	GetDlgItem(IDC_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);

		break;

	case 3:

		cv::cvtColor(imgSrc, imgSrc, COLOR_BGR2BGRA);

		break;

	default:

		break;

	}

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

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

	// 制作bitmapinfo(数据头)


	bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;

	bitInfo.bmiHeader.biWidth = imgSrc.cols;

	bitInfo.bmiHeader.biHeight = imgSrc.rows * judge;

	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_SHOWIMAGE)->GetDC();

	//绘图

	::StretchDIBits(

		pDC->GetSafeHdc(),

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

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

		imgSrc.data,

		&bitInfo,

		DIB_RGB_COLORS,

		SRCCOPY

	);

	ReleaseDC(pDC);

3、小结
利用第三方库opencv导入图片及完成相关操作是老师布置给我们的考试题目,在众多的实现方式中,我觉得mat类的是实现方式最为方便。本次题目的实践,让我更加熟悉mfc的操作,也增强了自己的学习能力。

本文地址:https://blog.csdn.net/weixin_46120503/article/details/106645342