欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MFC 第三方库 利用opencv的MAT类完成图片导入以及对图片进行翻转保存的操作

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