VC++开发数字图像处理系统2

来源:互联网 发布:java包装类有啥用 编辑:程序博客网 时间:2024/06/14 08:24

本节主要内容是将图片显示到控件上。

这里我们借助VS提供给我们的Gdiplus工具将图片显示到控件上。

一、首先简要介绍Gdiplus的配置方法:

1    在单文档应用程序中使用GDI+

创建一个单文档程序

1.1   添加包含文件和类库,方法:在stdafx.h文件中添加下面两行代码

#include

#pragma comment(lib,”gdiplus.lib”)

using namespace Gdiplus;

或者【项目】|【属性】,->【链接器】|【输入】->【附加依赖项】,在框中输入gdiplus.lib

1.2  在应用程序项目的应用类中,添加一个成员变量

ULONG_PTR m_gdiplusToken;
其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus:: GdiplusShutdown来关闭GDI+

1.3   在应用类中添加ExitInstance的重载来关闭GDI+

int CEXXXApp::ExitInstance()

{

                Gdiplus::GdiplusShutdown(m_gdiplusToken);

                return CWinApp::ExitInstance();

}

1.4  在应用类的InitInstance函数中添加GDI+的初始化代码

BOOL CEx_GDIPlusApp::InitInstance()

{

    ......

    CWinApp::InitInstance();

    Gdiplus::GdiplusStartupInput gdiplusStartupInput;

Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);

              ......

        }             

2    在基于对话框应用程序中使用GDI+

创建一个对话框应用程序

2.1 添加包含文件和类库,方法:在stdafx.h文件中添加下面两行代码

#include

#pragma comment(lib,”gdiplus.lib”)

using namespace Gdiplus;

2.2以下步骤同单文档应用程序

3    VS2010中的MFC中配置GDI+
首先,VS2010中已经有GDI+SDK包的,不需要额外下载
1)stdafx.h文件中加入下面3行代码,添加相应的头文件和库
  #pragma comment( lib, "gdiplus.lib" )
  #include "gdiplus.h"
  using namespace Gdiplus;
2)在应用程序项目的应用类中,添加一个成员变量或者定义一个全局变量ULONG_PTR m_gdiplusToken;
其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus:: GdiplusShutdown来关闭GDI+
3)使用GDI+函数前,先,最好放在OnInitDialog()中
 Gdiplus::GdiplusStartupInput gdiplusStartupInput;
 Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); 
4)使用完GDI+函数后,需要卸载GDI+
  Gdiplus::GdiplusShutdown(m_gdiplusToken);

这就是基本的配置了

当然,为了避免命名冲突,也可以将

#include

#pragma comment(lib,”gdiplus.lib”)

using namespace Gdiplus;

只添加到我们要使用Gdiplus库的头文件中去。

二、将图片显示到控件上

这里我们插入一个对话框资源:IDC_ThresholdDlg

再为这个资源添加一个类:CThreshholdDlg

CThreshholdDlg.h

 1 #pragma once 2  3 #include "resource.h" 4 #include "Dib.h" 5 #include "Threshold.h" 6 #pragma comment(lib,"gdiplus.lib") 7 #include <GdiPlus.h> 8 using namespace Gdiplus; 9 // CThresholdDlg 对话框10 11 class CThresholdDlg : public CDialog12 {13     DECLARE_DYNAMIC(CThresholdDlg)14 15 public:16     CThresholdDlg(CWnd* pParent = NULL);   // 标准构造函数17     virtual ~CThresholdDlg();18 19 // 对话框数据20     enum { IDD = IDD_Threshold };21 22 public:23     CDib dib;24     CStatic m_staBmp;25     CString m_BmpFilePath;26     CString m_BmpFileName;27 public:28     CDib* GetDib();29     void DrawBitmap();30 protected:31     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持32 33     DECLARE_MESSAGE_MAP()34 public:35     afx_msg void OnBnClickedOpenBmp();36     afx_msg void OnBnClickedOutsthreshold();37     afx_msg void OnBnClickedAdaptivethreshold();38     afx_msg void OnBnClickedSaveresult();39 };

CThresholdDlg.cpp

  1 // ThresholdDlg.cpp : 实现文件  2 //  3   4 #include "stdafx.h"  5 #include "ImgPro.h"  6 #include "ThresholdDlg.h"  7 #include "afxdialogex.h"  8   9  10 // CThresholdDlg 对话框 11  12 IMPLEMENT_DYNAMIC(CThresholdDlg, CDialog) 13  14 CThresholdDlg::CThresholdDlg(CWnd* pParent /*=NULL*/) 15     : CDialog(CThresholdDlg::IDD, pParent) 16 { 17  18 } 19  20 CThresholdDlg::~CThresholdDlg() 21 { 22 } 23  24 void CThresholdDlg::DoDataExchange(CDataExchange* pDX) 25 { 26     CDialog::DoDataExchange(pDX); 27     DDX_Control(pDX,IDC_STATIC,m_staBmp); 28 } 29  30  31 BEGIN_MESSAGE_MAP(CThresholdDlg, CDialog) 32     ON_BN_CLICKED(IDC_Open_BMP, &CThresholdDlg::OnBnClickedOpenBmp) 33     ON_BN_CLICKED(IDC_OutsThreshold, &CThresholdDlg::OnBnClickedOutsthreshold) 34     ON_BN_CLICKED(IDC_AdaptiveThreshold, &CThresholdDlg::OnBnClickedAdaptivethreshold) 35     ON_BN_CLICKED(IDC_SaveResult, &CThresholdDlg::OnBnClickedSaveresult) 36 END_MESSAGE_MAP() 37  38 CDib* CThresholdDlg::GetDib() 39 { 40     return &dib; 41 } 42  43 void CThresholdDlg::DrawBitmap(void) 44     { 45         CDC* pDC=m_staBmp.GetDC(); 46         Graphics graph(pDC->GetSafeHdc()); 47         CRect rect; 48         m_staBmp.GetClientRect(rect); 49         pDC->FillRect(rect, &CBrush(RGB(211, 211, 211))); 50         CSize size; 51         size.cx=rect.Width(); 52         size.cy=rect.Height(); 53         dib.Draw(pDC,CPoint(0,0),size); 54         ReleaseDC(pDC); 55     } 56 // CThresholdDlg 消息处理程序 57  58  59 void CThresholdDlg::OnBnClickedOpenBmp() 60 { 61     // TODO: 在此添加控件通知处理程序代码 62     LPCTSTR lpszFilter=L"BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg)|*.jpg|All Files(*.*)|*.*||"; 63     CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER,lpszFilter,NULL); 64     CFile file; 65     if(dlg.DoModal()==IDOK) 66     { 67         m_BmpFilePath=dlg.GetPathName(); 68         if(file.Open(m_BmpFilePath,CFile::modeRead|CFile::shareDenyNone,NULL)==0) 69         { 70             return; 71         } 72         dib.LoadFromFile(m_BmpFilePath); 73         DrawBitmap(); 74     } 75 } 76  77  78 void CThresholdDlg::OnBnClickedOutsthreshold() 79 { 80     // TODO: 在此添加控件通知处理程序代码 81     CThreshold threshold(GetDib()); 82     //threshold.m_pDib=GetDib(); 83     if(!dib.IsGrade()) 84         { 85             dib.RgbToGrade(); 86             DrawBitmap(); 87         } 88         else 89         {;} 90     threshold.OtusThreshold(); 91     DrawBitmap(); 92 } 93  94  95 void CThresholdDlg::OnBnClickedAdaptivethreshold() 96 { 97     // TODO: 在此添加控件通知处理程序代码 98     CThreshold threshold(GetDib()); 99     //threshold.m_pDib=GetDib();100     if(!dib.IsGrade())101         {102             dib.RgbToGrade();103             DrawBitmap();104         }105         else106         {;}107     threshold.AdaptiveThreshold();108     DrawBitmap();109 }110 111 112 void CThresholdDlg::OnBnClickedSaveresult()113 {114     // TODO: 在此添加控件通知处理程序代码115     LPCTSTR lpszFilter=L"BMP Files(*.bmp)|*.bmp|All Files(*.*)|*.*||";116         CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_EXPLORER,lpszFilter,NULL);117         if(dlg.DoModal()!=IDOK)118             return;119         dib.SaveToFile(dlg.GetPathName());120 }

Threshold.h

 1 #pragma once 2  3 #include "Dib.h" 4  5 class CThreshold 6 { 7 public: 8     CThreshold(); 9     CThreshold(CDib *pDib);10 public:11     ~CThreshold(void);12 public:13     void AdaptiveThreshold(void);14     void OtusThreshold(void);15 private:16     CDib * m_pDib; 17 };

Threshold.cpp

  1 #include "StdAfx.h"  2 #include "Threshold.h"  3 #include "math.h"  4   5 CThreshold::CThreshold()  6 {  7 }  8   9 CThreshold::CThreshold(CDib *pDib) 10 { 11     m_pDib = pDib; 12 } 13  14 CThreshold::~CThreshold(void) 15 { 16 } 17  18 //======================================================= 19 // 函数功能: 最大方差阈值分割 20 // 输入参数: 无 21 // 返回值:   无 22 //======================================================= 23 void CThreshold::OtusThreshold(void) 24 { 25     // 循环变量 26     int i, j; 27  28     // 原图数据区指针 29     LPBYTE p_data; 30     p_data = m_pDib->GetData(); 31  32     // 图像每行像素所占的字节数 33     int nLineByte = m_pDib->GetLineByte(); 34  35     // 图像的宽度 36     int nWidth = m_pDib->GetWidth(); 37  38     // 图像的高度 39     int nHeight = m_pDib->GetHeight(); 40  41     // 灰度直方图数组,并初始化 42     int nGrayHistogram[256]; 43     memset(nGrayHistogram, 0, sizeof(nGrayHistogram)); 44       45     // 统计各个灰度级对应的像素个数,并存放到灰度直方图数组中 46     int nPixel; 47     for (j = 0; j < nHeight; j ++) 48         for (i = 0; i < nWidth; i ++) 49         { 50             // 获取当前像素点的灰度值 51             nPixel = p_data[nLineByte * j + i];     52  53             // 对灰度值统计计数 54             nGrayHistogram[nPixel] ++;         55         } 56  57     // c0组和c1组的均值 58     float u0, u1; 59  60     // c0组和c1组的概率 61     float w0, w1; 62  63     // c0组的像素总数 64     int nCount0; 65  66     // 阈值和最佳阈值(对应方差最大时的阈值) 67     int nT, nBestT; 68  69     // 方差和最大方差 70     float fVaria, fMaxVaria = 0; 71  72     // 统计直方图中像素点的总数,并存放到nSum中 73     int nSum=0; 74     for(i = 0; i < 256; i ++) 75         nSum += nGrayHistogram[i]; 76  77  78     // 令阈值nT从0遍历到255 79     for(nT = 0; nT < 256; nT ++) 80     { 81         // 当阈值为nT时,计算c0组的均值和概率 82         u0 = 0; 83         nCount0 = 0; 84         for(i = 0; i <= nT; i++) 85         { 86             u0 += i * nGrayHistogram[i]; 87             nCount0 += nGrayHistogram[i]; 88         } 89         u0 /= nCount0; 90         w0 = (float) nCount0 / nSum; 91  92         // 当阈值为nT时,计算c1组的均值和概率 93         u1 = 0; 94         for(i = nT+1; i < 256; i ++) 95              u1 += i * nGrayHistogram[i]; 96         u1 /= (nSum - nCount0); 97         w1 = 1 - w0; 98  99         // 计算两组间的方差100         fVaria = w0 * w1 * (u0 - u1) * (u0 - u1);101 102         // 记录最大方差和最佳阈值103         if(fVaria > fMaxVaria)104         {105             fMaxVaria = fVaria;106             nBestT = nT;107         }108     }109 110     // 利用最佳阈值对原图像作分割处理111     for(j = 0; j < nHeight; j ++)112         for(i = 0; i < nWidth; i ++)113         {114             if(p_data[j * nLineByte + i] < nBestT)115                 p_data[j * nLineByte + i] = 0;116             else117                 p_data[j * nLineByte + i] = 255;118         }119 }120 121 122 //=======================================================123 // 函数功能: 自适应阈值分割124 // 输入参数: 无125 // 返回值:   无126 //=======================================================127 void CThreshold::AdaptiveThreshold(void)128 {129     // 循环变量130     int i,j;131     132     // 原图像数据区指针133     LPBYTE p_data;134     p_data = m_pDib->GetData();135 136     // 图像每行像素所占的字节数137     int nLineByte = m_pDib->GetLineByte();138 139     // 图像的宽度140     int nWidth = m_pDib->GetWidth();141 142     // 图像的高度143     int nHeight = m_pDib->GetHeight();144 145     // 局部阈值146     int nThreshold[2][2];147 148     // 子图像的灰度平均值149     int nAvgValue;150 151     // 对左上图像逐点扫描,计算该子图像的灰度平均值152     nAvgValue = 0;153     for(j = nHeight / 2; j < nHeight; j ++)154         for(i = 0; i < nWidth / 2; i ++)155             nAvgValue += p_data[j * nLineByte + i];156     nAvgValue /= ((nHeight / 2) * (nLineByte / 2));157 158     // 设置阈值为子图像的平均值159     nThreshold[0][0] = nAvgValue;160 161     // 对左上图像逐点扫描并进行阈值分割162     for(j = nHeight / 2; j < nHeight; j ++)163         for(i = 0; i < nWidth / 2; i ++)164         {165             if(p_data[j * nLineByte + i] < nThreshold[0][0])166                 p_data[j * nLineByte + i] = 0;167             else168                 p_data[j * nLineByte + i] = 255;169         }170 171     // 对右上图像逐点扫描,计算该子图像的灰度平均值172     nAvgValue = 0;173     for(j = nHeight / 2; j < nHeight; j ++)174         for(i = nWidth / 2; i < nWidth; i ++)175             nAvgValue += p_data[j * nLineByte + i];176     nAvgValue /= ((nHeight / 2) * (nLineByte / 2));177 178     // 设置阈值为子图像的平均值179     nThreshold[0][1] = nAvgValue;180 181     // 对右上图像逐点扫描并进行阈值分割182     for(j = nHeight / 2; j < nHeight; j ++)183         for(i = nWidth / 2; i < nWidth; i ++)184         {185             if(p_data[j * nLineByte + i] < nThreshold[0][0])186                 p_data[j * nLineByte + i] = 0;187             else188                 p_data[j * nLineByte + i] = 255;189         }190 191     // 对左下图像逐点扫描,计算该子图像的灰度平均值192     nAvgValue = 0;193     for(j = 0; j < nHeight / 2; j ++)194         for(i = 0; i < nWidth / 2; i ++)195             nAvgValue += p_data[j * nLineByte + i];196     nAvgValue /= ((nHeight / 2) * (nLineByte / 2));197 198     // 设置阈值为子图像的平均值199     nThreshold[1][0] = nAvgValue;200 201     // 对左下图像逐点扫描并进行阈值分割202     for(j = 0; j < nHeight / 2; j ++)203         for(i = 0; i < nWidth / 2; i ++)204         {205             if(p_data[j * nLineByte + i] < nThreshold[0][0])206                 p_data[j * nLineByte + i] = 0;207             else208                 p_data[j * nLineByte + i] = 255;209         }210 211     // 对右下图像逐点扫描,计算该子图像的灰度平均值212     nAvgValue = 0;213     for(j = 0; j < nHeight / 2; j ++)214         for(i = nWidth / 2; i < nWidth; i ++)215             nAvgValue += p_data[j * nLineByte + i];216     nAvgValue /= ((nHeight / 2) * (nLineByte / 2));217 218     // 设置阈值为子图像的平均值219     nThreshold[1][1] = nAvgValue;220 221     // 对右下下图像逐点扫描并进行阈值分割222     for(j = 0; j < nHeight / 2; j ++)223         for(i = nWidth / 2; i < nWidth;i ++)224         {225             if(p_data[j * nLineByte + i] < nThreshold[0][0])226                 p_data[j * nLineByte + i] = 0;227             else228                 p_data[j * nLineByte + i] = 255;229         }230 }

最后我们在视图类的实现(C*View.cpp)文件里添加命令响应函数:

1 void CImgProView::OnThreshhold()2 {3     // TODO: 在此添加命令处理程序代码4     CThresholdDlg thresholddlg;5     thresholddlg.DoModal();6 }

注:Dib.h和Dib.cpp文件在

VC++2010开发数字图像系统1

中给出

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 跟越南人离婚孩子中国户口9怎么办 老婆是个越南人至今没户口怎么办 等离子屏z板链接处排线打火怎么办 等离子自动调焊的成形不好怎么办 村里内村道路中间被抢占了怎么办 华为换电池之后卡没反应怎么办 汽车钥匙换电池后没反应怎么办 汽车解锁换电池后没反应怎么办 包裹显示待收件人向海关申报怎么办 在越南签证被公安扣了怎么办 酷派手机收不到验证码怎么办 苹果想把图片上的字盖上怎么办 婴儿自己把眼珠子抠红了怎么办 如果美陆战队员进入台湾那怎么办? 顺产生完小孩吸不通奶怎么办 耐克空军一号白色底发黄怎么办 中行网银u盾丢了怎么办 有人用你的手机号码不停注册怎么办 获得公开你微信头像的权限是怎么办 手机能进的网站电脑进不去怎么办 苹果8p下不了微信怎么办 苹果手机版本过底不能下微信怎么办 手机打开视频跳转到qq是怎么办 淘宝店铺显示服务竟然出错了怎么办 母羊下完羊羔把羊衣吃了怎么办? 移植后56天有黑色东西怎么办 我家的金丝熊浑身都是尿怎么办 一键启动车钥匙丢了怎么办 把爷爷的遗物弄丢了怎么办 如果你娶了一个傻子你怎么办 在国外订机票手机收不到信息怎么办 网上买机票名字写错了怎么办 买机票名字错了一个字怎么办 微店没收到货却显示已收货怎么办? 手机存的照片误删了怎么办 魔兽世界把要用的装备分解了怎么办 邻居家的狗见到我就叫怎么办 我的世界玩的时间长会卡应该怎么办 网易我的世界密码账号都忘了怎么办 我的世界创建世界画面乱码了怎么办 网易我的世界云端存档不够用怎么办