mfc制作图像处理软件总结(一)
2014-07-24 14:34
471 查看
最近老师让做一个处理图像的小软件,用了大概一个星期做出来了成品,MFC上我算是新手,一路摸索过来也算是收获不少吧,现在软件也做完了,给自己总结一下在学习过程中的收获和不足。
首先放出一下软件的运行截图,主要是做了灰度图像的几何变换、正交变换、图像增强、二值化处理、形态学处理、图像分割等功能。代码主要参考了《visual c++数字图象处理技术详解》以及网上的一些技术文章,完整的工程已上传至csdn:http://download.csdn.net/detail/zzucode/7672489
灰度图像处理主要操作的是设备无关位图(DIB),由于mfc本身没有提供DIB的一个完整的类,只是提供了一些API接口和结构体,因此需要自己创建一个DIB类,主要实现位图的载入,保存,绘制及返回位图信息等操作。
首先使用mfc向导创建一个单文档应用程序,不使用unicode编码,然后在源文件中添加DIB类的头文件Dib.h和Dib.cpp,具体的头文件如下:
将Dib的实现文件添加进来之后,接下来就需要载入图像并在文档客户区显示,首先在工程C**Doc类的头文件中声明一个Dib类的对象并定义一些操作:
然后在C**Doc类的实现文件的构造函数中添加
首先放出一下软件的运行截图,主要是做了灰度图像的几何变换、正交变换、图像增强、二值化处理、形态学处理、图像分割等功能。代码主要参考了《visual c++数字图象处理技术详解》以及网上的一些技术文章,完整的工程已上传至csdn:http://download.csdn.net/detail/zzucode/7672489
灰度图像处理主要操作的是设备无关位图(DIB),由于mfc本身没有提供DIB的一个完整的类,只是提供了一些API接口和结构体,因此需要自己创建一个DIB类,主要实现位图的载入,保存,绘制及返回位图信息等操作。
首先使用mfc向导创建一个单文档应用程序,不使用unicode编码,然后在源文件中添加DIB类的头文件Dib.h和Dib.cpp,具体的头文件如下:
class CDib { public: CDib(); virtual ~CDib(); //operations public: // 用于操作DIB的函数声明 BOOL DrawDib(HDC, LPRECT,HGLOBAL, LPRECT,CPalette*);//显示位图 BOOL ConstructPalette(HGLOBAL,CPalette* ); //构造逻辑调色板 LPSTR GetBits(LPSTR); //取得位图数据的入口地址 DWORD GetWidth(LPSTR); //取得位图的宽度 DWORD GetHeight(LPSTR); //取得位图的高度 WORD GetPalSize(LPSTR); //取得调色板的大小 WORD GetColorNum(LPSTR); //取得位图包含的颜色数目 WORD GetBitCount(LPSTR); //取得位图的颜色深度 HGLOBAL CopyObject(HGLOBAL); //用于复制位图对象 BOOL SaveFile(HGLOBAL , CFile&); //存储位图为文件 HGLOBAL LoadFile(CFile&); //从文件中加载位图 BOOL IsEmpty(); // 在对图像进行处理时,针对位图的字节宽度必须是4的倍数的这一要求, //我们设计了函数GetRequireWidth,来处理这种比较特殊的情况 int GetReqByteWidth(int ); //转换后的字节数 long GetRectWidth(LPCRECT ); //取得区域的宽度 long GetRectHeight(LPCRECT); //取得区域的高度 public: void ClearMemory(); void InitMembers(); public: LPBITMAPINFO lpbminfo;// 指向BITMAPINFO结构的指针 LPBITMAPINFOHEADER lpbmihrd; //指向BITMAPINFOHEADER结构的指针 BITMAPFILEHEADER<span style="white-space:pre"> </span>bmfHeader; //BITMAPFILEHEADER结构 LPSTR<span style="white-space:pre"> </span>lpdib; //指向DIB的指针 LPSTR<span style="white-space:pre"> </span>lpDIBBits; // DIB像素指针 DWORD<span style="white-space:pre"> </span>dwDIBSize; //DIB大小 HGLOBAL<span style="white-space:pre"> </span>m_hDi //DIB对象的句柄 RGBQUAD*<span style="white-space:pre"> </span>lpRgbQuag; //指向颜色表的指针 };DIB类的实现文件太长,就不再贴出来了,《visual c++数字图象处理技术详解》上有完整的源码,有感兴趣的朋友可以自己去看。
将Dib的实现文件添加进来之后,接下来就需要载入图像并在文档客户区显示,首先在工程C**Doc类的头文件中声明一个Dib类的对象并定义一些操作:
// 特性 public: CDib m_dib; //声明一个DIB对象 CString m_szPathName;//图片文件路径 // 操作 public: HGLOBAL GetHObject() const //获取Dib对象的句柄 { return m_hDIB;} CPalette *GetDocPal() const //获取调色板指针 { return m_palDIB;} CSize GetDocDimension() const // { return m_sizeDoc;} void UpdateObject(HGLOBAL hDIB); //更新DIB对象 // 实现 public: void SetDib(); //获取Dib对象 public: HGLOBAL m_hDIB; CPalette *m_palDIB; CSize m_sizeDoc;
然后在C**Doc类的实现文件的构造函数中添加
// TODO: 在此添加一次性构造代码 m_hDIB = NULL; m_palDIB = NULL; m_sizeDoc = CSize(1,1);在析构函数中添加
if (m_hDIB != NULL) //判断是否有dib对象 { ::GlobalFree(m_hDIB); } if (m_palDIB != NULL) //判断是否有调色板 { delete m_palDIB; }然后重载C**Doc类的OnOpenDocument函数
// TODO: 在此添加您专用的创建代码 CFile file; if (!file.Open(lpszPathName,CFile::modeRead | CFile::shareDenyWrite)) { //只读方式打开文件 return FALSE; } DeleteContents();//删除文档中数据,确保载入图像数据之前文档为空 m_hDIB = m_dib.LoadFile(file); m_szPathName = lpszPathName; if (m_hDIB == NULL) { return FALSE; } SetDib(); if (m_hDIB == NULL) { AfxMessageBox("读取图像时出错!"); return FALSE; } SetPathName(lpszPathName);//设置文件名称 return TRUE;其中setdib函数主要是在载入位图数据后创建调色板,具体代码如下
void CImgProcessDoc::SetDib() { LPSTR lpdib = (LPSTR) ::GlobalLock(m_hDIB);//保持图片数据内存一直有效 if (m_dib.GetWidth(lpdib) > INT_MAX ||m_dib.GetHeight(lpdib) > INT_MAX)// 判断图像是否过大 { ::GlobalUnlock((HGLOBAL) m_hDIB); ::GlobalFree((HGLOBAL) m_hDIB); // 释放DIB对象 m_hDIB = NULL;// 设置DIB为空 AfxMessageBox("初始化失败!"); return; } m_sizeDoc = CSize((int)m_dib.GetWidth(lpdib), (int)m_dib.GetHeight(lpdib));// 设置文档大小 ::GlobalUnlock((HGLOBAL) m_hDIB); m_palDIB = new CPalette;// 创建新调色板 if (m_palDIB == NULL)// 判断是否创建成功 { ::GlobalFree((HGLOBAL) m_hDIB); // 失败 m_hDIB = NULL;// 设置DIB对象为空 return; } // 调用CreateDIBPalette来创建调色板 if (m_dib.ConstructPalette(m_hDIB, m_palDIB) == NULL) { delete m_palDIB;// 删除 m_palDIB = NULL;// 设置为空 return;// 返回空 } }这时候编译工程并运行,点击打开一个位图文件就可以将位图文件的信息和数据载入内存,但是打开之后并没有在客户区显示,这时候需要重载C**View类的OnDraw函数
// TODO: 在此处为本机数据添加绘制代码 HGLOBAL hDIB = pDoc->GetHObject(); // 判断DIB是否为空 if (hDIB != NULL) { LPSTR lpDibSection = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); // 获取DIB宽度 int cxDIB = (int) pDoc->m_dib.GetWidth(lpDibSection); // 获取DIB高度 int cyDIB = (int) pDoc->m_dib.GetHeight(lpDibSection); ::GlobalUnlock((HGLOBAL) hDIB); CRect rcDIB; rcDIB.top = rcDIB.left = 0; rcDIB.right = cxDIB; rcDIB.bottom = cyDIB; CRect rcDest= rcDIB; // 输出DIB pDoc->m_dib.DrawDib(pDC->m_hDC, &rcDest, pDoc->GetHObject(), &rcDIB, pDoc->GetDocPal()); }编译工程并运行,就可以打开文件并显示到程序的客户区了。
相关文章推荐
- MFC图像处理软件 地图 不显示图片对话框
- 基于mfc的数字图像处理的小软件pdd的诞生-打开图片及保存图片
- 基于MFC和OpenCV的图像处理小软件
- 基于GDI+的图像处理软件制作(VC)
- 如何制作图像处理软件?
- 基于mfc数字图像处理的小软件pdd-转换图片成RGB通道,反色,黑白,灰度图片
- 基于MFC和OpenCV的图像处理小软件(续)
- ZYNQ HLS图像处理加速总结(二)——Processing System软件部分
- 基于mfc数字图像处理的小软件pdd-改变图片的大小
- 用C#制作图像处理软件及其原理
- Atitit 软件项目的一整套解决方案(gui界面,中间,存储数据库,图像处理,全文搜索)attilax总结
- MFC多文档视图界面(MDI)搭建图像处理框架程序总结
- 基于mfc数字图像处理的小软件pdd-量化灰度图像
- MFC界面之通过软件制作图像序列
- MFC 图形图像处理 -- 总结
- 终于决定总结自己的图像处理库
- 收集的网络上大型的开源图像处理软件代码(提供下载链接)
- 一款不错的图像处理软件(含源码)
- DALSA Coreco - 图像处理软件(Sapera LT )
- [原创]MFC中的多线程处理问题总结