MFC 第三方库 利用opencv的MAT类完成图片导入以及对图片进行翻转保存的操作
程序员文章站
2022-06-16 17:47:07
配置opencv在操作之前,我们应该先进行opencv的配置,如果不提前配置好,当我们在用Opencv库里的函数是会报错。关于这点,网上已经有很多配置的博客供大家参考,我就不赘述了,这里放上我配置时看的那篇博客,希望能帮到大家https://blog.csdn.net/shuiyixin/article/details/105998661;(因为我配置的时候,无论如何都做不到一次配置一劳永逸,应该是我的方法问题。所以如果你也是这样,建议将配置好的信息保存下来,生成配置文件,下次使用的时候就可以直接在“....
-
配置opencv
在操作之前,我们应该先进行opencv的配置,如果不提前配置好,当我们在用Opencv库里的函数是会报错。关于这点,网上已经有很多配置的博客供大家参考,我就不赘述了,这里放上我配置时看的那篇博客,希望能帮到大家https://blog.csdn.net/shuiyixin/article/details/105998661;
(因为我配置的时候,无论如何都做不到一次配置一劳永逸,应该是我的方法问题。所以如果你也是这样,建议将配置好的信息保存下来,生成配置文件,下次使用的时候就可以直接在“属性”界面,DebugX64和ReleaseX64下导入就可以用了,也挺方便的) -
具体操作
打开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