数字图像处理实验1——用MFC编程显示图像

数字图像处理实验

2021.3.6——2021.3.7


文章目录

  • 数字图像处理实验
  • 前言
  • 一、新建项目
  • 二、查看代码
  • 三、编写代码
    • 1.修改头文件
    • 2.编辑程序窗口
    • 3.编写事件处理程序
  • 四、测试程序
  • 总结


前言

本实验创建MFC应用程序,实现通过窗口选择图像文件,并将图像显示出来的功能。


一、新建项目

在VisualStudio 2017中新建项目,创建“MFC应用程序”,项目名为“ImageProcessing”,选择项目路径。
数字图像处理实验1——用MFC编程显示图像_第1张图片
按下述步骤完成项目创建:
数字图像处理实验1——用MFC编程显示图像_第2张图片
选择CScrollView,如果图像大小超过窗口,可以拖动滚动条。
数字图像处理实验1——用MFC编程显示图像_第3张图片
点击“完成”,完成项目创建。现在VisualStudio已经为我们创建好了程序的框架。
数字图像处理实验1——用MFC编程显示图像_第4张图片

点击运行,可以看到虽然自己一行代码都没写,但应用程序已经可以运行了,只是里面的选项都没有对应的功能。
数字图像处理实验1——用MFC编程显示图像_第5张图片

二、查看代码

查看源文件列表。
数字图像处理实验1——用MFC编程显示图像_第6张图片
因为目前只实现打开并显示图片的功能,只涉及对文件的操作和显示的视图操作,故只修改ImageProcessingView.cpp和ImageProcessingDoc.cpp文件。
查看代码可以看到,在这里Visual Studio已经为我们生成好了主要的程序框架,源文件都包括了对应的头文件
数字图像处理实验1——用MFC编程显示图像_第7张图片

三、编写代码

1.修改头文件

查看并修改ImageProcessingDoc.cpp对应的头文件ImageProcessingDoc.h。
对CImageProcessingDoc类添加新的成员变量,用于存放“原始图像”和“处理后的图像”,图片文件有多种格式(如PEG、GIF、BMP和PNG格式),对每一种格式都自己手动实现解码非常麻烦,而CImage类已经提供了相应的接口函数,可以装入、显示、转换和保存多种格式的图像文件,我们只需调用就可以直接打开图片,打开后图像将以统一的格式放在CImage类的对象中

class CImageProcessingDoc : public CDocument
{
protected: // 仅从序列化创建
	CImageProcessingDoc() noexcept;
	DECLARE_DYNCREATE(CImageProcessingDoc)

// 特性
public:
	CImage m_sImage;	//原始图像
	CImage m_rImage;	//处理后的图像
	
//省略其余

2.编辑程序窗口

打开“资源视图”,可以看到这里面有组成程序窗口的各种组件,包括Dialog(对话框),Icon(图标),Menu(菜单)等等。
数字图像处理实验1——用MFC编程显示图像_第8张图片
选择Menu中的IDR_MAINFEAME,可以看到这里可以对主菜单中的各种选项进行编辑。
数字图像处理实验1——用MFC编程显示图像_第9张图片
在此程序中不需要新建文件的功能,故右键“新建”项将其删除。同样方法删除“编辑”项。
数字图像处理实验1——用MFC编程显示图像_第10张图片
点击“打开”选项,在右下角的“属性”框中对选项中的文字内容(即“Caption”栏)进行编辑,将“打开”改为“打开图像文件”。
数字图像处理实验1——用MFC编程显示图像_第11张图片本程序只实现打开图片并显示的功能,右键刚刚修改的“打开图像文件”选项,点击“添加事件处理程序”。
数字图像处理实验1——用MFC编程显示图像_第12张图片

3.编写事件处理程序

按照本文之前的说明,与打开文件相关的是文档类,在“类列表”中选择“CImageProcessingDoc”,点击“添加编辑”。
数字图像处理实验1——用MFC编程显示图像_第13张图片
可以看到在ImageProcessingDoc.cpp文件(功能实现代码)中新增的OnFileOpen()函数,编写这个函数。
数字图像处理实验1——用MFC编程显示图像_第14张图片
该函数主要实现了 通过窗口选择图像文件,并加载到CImage类对象中 的功能。函数代码如下:

void CImageProcessingDoc::OnFileOpen()
{
	// TODO: 在此添加命令处理程序代码
	CString strFilter;
	CSimpleArray<GUID>  aguidFileTypes;
	HRESULT hResult;

	// 获取CImage支持的图像文件的过滤字符串
	hResult = m_sImage.GetExporterFilterString(strFilter, aguidFileTypes, _T("All Image Files"));
	if (FAILED(hResult))
	{
		AfxMessageBox(_T("GetExporterFilter函数失败!"));
		return;
	}

	CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, strFilter);
	if (IDOK != dlg.DoModal())
		return;

	// 销毁原有文件内容
	m_sImage.Destroy(); 
	m_rImage.Destroy();

	// 将外部图像文件装载到CImage对象中
	hResult = m_sImage.Load(dlg.GetPathName());
	if (FAILED(hResult))
	{
		AfxMessageBox(_T("图像文件加载失败!"));
		return;
	}

	// 要求图像为24位真彩图,32位相对于24位还多8位存放透明度
	if (m_sImage.GetBPP() != 24)
	{
		m_sImage.Destroy();
		AfxMessageBox(_T("只处理24位色图像!"));
		return;
	}

	// 设置主窗口标题栏内容
	CString str;
	str.LoadString(AFX_IDS_APP_TITLE);
	AfxGetMainWnd()->SetWindowText(str + " - " + dlg.GetFileName());
	InvalidateRect(NULL, NULL, FALSE);	// 刷新窗口
}

同样在ImageProcessingView.cpp文件中,编写OnDraw()函数。代码如下:

void CImageProcessingView::OnDraw(CDC* pDC)
{
	CImageProcessingDoc* pDoc = GetDocument();	//获取文档类Doc对象的指针
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// 原始图像显示在窗口左上角
	if (!pDoc->m_sImage.IsNull())
		pDoc->m_sImage.Draw(pDC->m_hDC, 0, 0);

	// 目标图像从原始图像右边10个像素的位置开始显示
	if (!pDoc->m_rImage.IsNull())
		pDoc->m_rImage.Draw(pDC->m_hDC, pDoc->m_sImage.GetWidth() + 10, 0);
}

四、测试程序

至此代码编写完成,点击运行程序,测试功能。可以看到“文件”菜单下的“打开图像文件”选项。
数字图像处理实验1——用MFC编程显示图像_第15张图片
点击“打开图像文件”,选择lena的24位bmp图片。
数字图像处理实验1——用MFC编程显示图像_第16张图片
可以看到图像显示在应用窗口中,说明实现了选择图片文件并显示的功能,完成了实验目标。
数字图像处理实验1——用MFC编程显示图像_第17张图片


总结

本次实验是对于MFC项目的初步应用实践,对VisualStudio C++中图像相关类(如CImage)有了初步的了解,并掌握了相关的数字图像基础知识,如采样、量化等等。

你可能感兴趣的:(c++,图像处理,mfc,visual,studio)