计算机图形学 实验二

  • 格式:doc
  • 大小:731.50 KB
  • 文档页数:27

1 计算机科学系实验报告(首页) 课程名称 计算机图形学 班级 12网络2

实验名称 VC存取BMP图像及其几何变换 教导教师 吴志攀

姓名 李文森 学号 1214080613213 日期 2014 .11.21

一、实验目的 1. 掌握VC中BMP图像的存取方法; 2. 掌握BMP图像平移、旋转、变比等几何变换。 二、实验设备与环境

TC2.0,Windows XP 三、实验内容、程序清单及运行结果 1.打开VC++ 6.0,选择File|New进入界面。在Projects中选择MFC AppWinzard(exe),在Project name中输入项目名称,本例为ReadBMP,在Location中输入项目要保存的文件夹。点击“OK”进入下一步。如下图2-1所示。

图2-1 2.选择文档类型。在本例中使用的是单文档视图结构,所以这里选择Single 2

document。其余部分设置使用VC++ 6.0的默认设置,点击“Finish”完成项目创建。如下图2-2所示:

图2-2 3.为了将BMP中的数据读入到内存中,在项目中导入专门处理BMP文件头和数据的文件:DIBAPI.H和DIBAPI.CPP,在其中实现对BMP文件的大部分处理。 在工作区“FileView”选项卡的“Header Files”中点右键,在“添加文件到目录”添加“DIBAPI.H”文件。如下图2-3所示:

图2-3 3

在工作区“FileView”选项卡的“Source Files”中点右键,在“添加文件到目录”添加“DIBAPI.CPP”文件。 并在“ReadBMPDoc.h”添加头文件"dibapi.h",如下所示: #include "dibapi.h"

4.在CReadBMPDoc类中添加保护成员变量CPalette* m_palDIB,HDIB m_hDIB和CSize m_sizeDoc。m_hDIB用于保存当前BMP图像句柄,m_palDIB用于指向BMP图像对应的调色板。 protected: HDIB m_hDIB; CPalette* m_palDIB; CSize m_sizeDoc;

5.为了取得保存在当前文档中的HDIB和Palette数据,在“ReadBMPDoc.h”的CReadBMPDoc类中添加方法:GetHDIB,GetDocPalette和GDocSize。如下所示: // Attributes public: HDIB GetHDIB() const { return m_hDIB; } CPalette* GetDocPalette() const { return m_palDIB; } CSize GetDocSize() const { return m_sizeDoc; }

在CReadBMPDoc.cpp的构造函数中初始化: // 初始化变量 m_hDIB = NULL; m_palDIB = NULL; m_sizeDoc = CSize(1,1);

6.响应类CReadBMPDoc OnOpenDocument事件,以实现打开文件的操作。 从View|ClassWizard进入MFC ClassWizard界面,在Message Maps选项中完成消息映射。下图2-4所示: 4

图2-4 在BOOL CReadBMPDoc::OnOpenDocument(LPCTSTR lpszPathName)函数中添加如下代码: //if (!CDocument::OnOpenDocument(lpszPathName)) //return FALSE;

// TODO: Add your specialized creation code here //return TRUE; CFile file; CFileException fe;

// 打开文件 if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe)) { // 失败 ReportSaveLoadException(lpszPathName, &fe, FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);

// 返回FALSE return FALSE; }

DeleteContents(); // 更改光标形状 BeginWaitCursor(); 5

// 尝试调用ReadDIBFile()读取图像 TRY { m_hDIB = ::ReadDIBFile(file); } CATCH (CFileException, eLoad) { // 读取失败 file.Abort();

// 恢复光标形状 EndWaitCursor();

// 报告失败 ReportSaveLoadException(lpszPathName, eLoad, FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);

// 设置DIB为空 m_hDIB = NULL;

// 返回FALSE return FALSE; } END_CATCH

// 初始化DIB InitDIBData();

// 恢复光标形状 EndWaitCursor();

// 判断读取文件是否成功 if (m_hDIB == NULL) { // 失败,可能非BMP格式 CString strMsg; strMsg = "读取图像时出错!可能是不支持该类型的图像文件!";

// 提示出错 6

MessageBox(NULL, strMsg, "系统提示", MB_ICONINFORMATION | MB_OK);

// 返回FALSE return FALSE; }

// 设置文件名称 SetPathName(lpszPathName);

// 初始化胀标记为FALSE SetModifiedFlag(FALSE);

// 返回TRUE return TRUE;

并在ReadBMPDoc.cpp添加Public成员函数InitDIBData,并添加如下程序: void CReadBMPDoc::InitDIBData() { // 初始化DIB对象

// 判断调色板是否为空 if (m_palDIB != NULL) { // 删除调色板对象 delete m_palDIB;

// 重置调色板为空 m_palDIB = NULL; }

// 如果DIB对象为空,直接返回 if (m_hDIB == NULL) { // 返回 return; }

LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); 7

// 判断图像是否过大 if (::DIBWidth(lpDIB) > INT_MAX ||::DIBHeight(lpDIB) > INT_MAX) { ::GlobalUnlock((HGLOBAL) m_hDIB);

// 释放DIB对象 ::GlobalFree((HGLOBAL) m_hDIB);

// 设置DIB为空 m_hDIB = NULL;

CString strMsg; strMsg = "BMP图像太大!";

// 提示用户 MessageBox(NULL, strMsg, "系统提示", MB_ICONINFORMATION | MB_OK);

// 返回 return; }

// 设置文档大小 m_sizeDoc = CSize((int) ::DIBWidth(lpDIB), (int) ::DIBHeight(lpDIB));

::GlobalUnlock((HGLOBAL) m_hDIB); // 创建新调色板 m_palDIB = new CPalette;

// 判断是否创建成功 if (m_palDIB == NULL) { // 失败,可能是内存不足 ::GlobalFree((HGLOBAL) m_hDIB);

// 设置DIB对象为空 m_hDIB = NULL;

// 返回 8

return; }

// 调用CreateDIBPalette来创建调色板 if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL) { // 返回空,可能该DIB对象没有调色板

// 删除 delete m_palDIB;

// 设置为空 m_palDIB = NULL;

// 返回 return; } } // 调用CreateDIBPalette来创建调色板 if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL) { // 返回空,可能该DIB对象没有调色板

// 删除 delete m_palDIB;

// 设置为空 m_palDIB = NULL;

// 返回 return; }

7.完成图片的打开操作之后,图片的数据就已经被保存在程序中,为了将图片显示出来还需要响应类CReadBMPView的OnDraw事件,在其中完成图像显示。 void CReadBMPView::OnDraw(CDC* pDC) { //CReadBMPDoc* pDoc = GetDocument(); //ASSERT_VALID(pDoc); // TODO: add draw code for native data here