[GDAL]3.影像金字塔构建

今天又考了一次六级,不知道结果怎么样!

贴出昨天的工作,采用MFC改写的构建影像金字塔的代码,感觉自己对于C++的基础知识掌握的还是有欠缺:

1. 进度条基类CProcessBase

View Code
 1 #pragma once
 2 class CProcessBase:CObject
 3 {
 4 public:
 5     CProcessBase(void);
 6     ~CProcessBase(void);
 7     protected:
 8     /*! 进度信息 */  
 9     CString m_strMessage;  
10     /*! 进度值 */  
11     double m_dPosition;       
12     /*! 进度个数 */  
13     int m_iStepCount;         
14     /*! 进度当前个数 */  
15     int m_iCurStep;           
16     /*! 是否取消,值为false时表示计算取消 */  
17     
18     public:
19     bool m_bIsContinue; 
20      virtual void SetMessage(const char* pszMsg) = 0;  
21   
22     /** 
23     * @brief 设置进度值 
24     * @param dPosition      进度值 
25     * @return 返回是否取消的状态,true为不取消,false为取消 
26     */  
27     virtual bool SetPosition(double dPosition) = 0;  
28   
29     /** 
30     * @brief 进度条前进一步,返回true表示继续,false表示取消 
31     * @return 返回是否取消的状态,true为不取消,false为取消 
32     */  
33     virtual bool StepIt() = 0;  
34   
35     /** 
36     * @brief 设置进度个数 
37     * @param iStepCount     进度个数 
38     */  
39     virtual void SetStepCount(int iStepCount)  
40     {  
41         ReSetProcess();   
42         m_iStepCount = iStepCount;  
43     }  
44   
45     /** 
46     * @brief 获取进度信息 
47     * @return 返回当前进度信息 
48     */  
49     CString GetMessage()  
50     {  
51         return m_strMessage;  
52     }  
53   
54     /** 
55     * @brief 获取进度值 
56     * @return 返回当前进度值 
57     */  
58     double GetPosition()  
59     {  
60         return m_dPosition;  
61     }  
62   
63     /** 
64     * @brief 重置进度条 
65     */  
66     void ReSetProcess()  
67     {  
68         m_dPosition = 0.0;  
69         m_iStepCount = 100;  
70         m_iCurStep = 0;  
71         m_bIsContinue = true;  
72     }  
73 };

CProcessBase实现文件:

View Code
 1 #include "StdAfx.h"
 2 #include "ProcessBase.h"
 3 
 4 
 5 CProcessBase::CProcessBase(void)
 6 {
 7     m_dPosition = 0.0;  
 8     m_iStepCount = 100;  
 9     m_iCurStep = 0;  
10     m_bIsContinue = true;  
11 }
12 
13 
14 CProcessBase::~CProcessBase(void)
15 {
16 }

 2. 进度条子类DlgProcess

View Code
 1 #pragma once
 2 #include "ProcessBase.h"
 3 #include "afxwin.h"
 4 #include "afxcmn.h"
 5 // DlgProcess 对话框
 6 
 7 class DlgProcess : public CDialog,public CProcessBase
 8 {
 9     DECLARE_DYNAMIC(DlgProcess)
10 
11 public:
12     DlgProcess(CWnd* pParent = NULL);   // 标准构造函数
13     virtual ~DlgProcess();
14 
15     void SetMessage(const char* pszMsg);  
16   
17     /** 
18     * @brief 设置进度值 
19     * @param dPosition      进度值 
20     */  
21     bool SetPosition(double dPosition);  
22   
23     /** 
24     * @brief 进度条前进一步 
25     */  
26     bool StepIt();  
27     void updateProgress(int);  
28 
29 
30 
31 // 对话框数据
32     enum { IDD = IDD_Progress };
33 
34 protected:
35     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
36 
37     DECLARE_MESSAGE_MAP()
38 public:
39     CStatic txtInfo;
40     CProgressCtrl proShow;
41     bool wasCanceled;
42     afx_msg void OnBnClickedCancel();
43 };

DlgProcess实现文件:

View Code
 1 // DlgProcess.cpp : 实现文件
 2 //
 3 
 4 #include "stdafx.h"
 5 #include "ImageInfo.h"
 6 #include "DlgProcess.h"
 7 #include "afxdialogex.h"
 8 #include "ProcessBase.h"
 9 
10 // DlgProcess 对话框
11 
12 IMPLEMENT_DYNAMIC(DlgProcess, CDialog)
13 
14 DlgProcess::DlgProcess(CWnd* pParent /*=NULL*/)
15     : CDialog(DlgProcess::IDD, pParent)
16 {
17     m_dPosition = 0.0;  
18     m_iStepCount = 100;  
19     m_iCurStep = 0;
20     wasCanceled=false;
21 }
22 
23 DlgProcess::~DlgProcess()
24 {
25 }
26 
27 void DlgProcess::DoDataExchange(CDataExchange* pDX)
28 {
29     CDialog::DoDataExchange(pDX);
30     DDX_Control(pDX, IDC_ProcessInfo, txtInfo);
31     DDX_Control(pDX, IDC_PROGRESS_SHOW, proShow);
32 }
33 
34 void DlgProcess::SetMessage(const char* pszMsg)  
35 {  
36     if (pszMsg != NULL)  
37     {  
38         m_strMessage = pszMsg;  
39         SetDlgItemText(IDC_ProcessInfo,CString(pszMsg));  
40     }  
41 }  
42 
43 /** 
44 * @brief 设置进度值 
45 * @param dPosition      进度值 
46 */  
47 bool DlgProcess::SetPosition(double dPosition)  
48 {  
49     m_dPosition = dPosition;  
50 
51     proShow.SetPos(min( 100u, (short)(m_dPosition*100.0)));  
52     
53     if(this->wasCanceled)  
54         return false;  
55 
56     return true;  
57 }  
58 
59 /** 
60 * @brief 进度条前进一步,返回false表示终止操作 
61 */  
62 bool DlgProcess::StepIt()  
63 {  
64     m_iCurStep ++;  
65     m_dPosition = m_iCurStep*1.0 / m_iStepCount;  
66 
67     proShow.SetPos( min( 100u, (short)( m_dPosition*100.0 ) ) );  
68     
69     if(this->wasCanceled)  
70         return false;  
71 
72     return true;  
73 }  
74 
75 void DlgProcess::updateProgress(int step)  
76 {  
77     proShow.SetPos(step);     
78 }  
79 
80 
81 BEGIN_MESSAGE_MAP(DlgProcess, CDialog)
82     ON_BN_CLICKED(IDC_CANCEL, &DlgProcess::OnBnClickedCancel)
83 END_MESSAGE_MAP()
84 
85 
86 // DlgProcess 消息处理程序
87 
88 
89 void DlgProcess::OnBnClickedCancel()
90 {
91     wasCanceled=true;
92     // TODO: 在此添加控件通知处理程序代码
93 }

3. 对话框界面OverView

View Code
 1 #pragma once
 2 
 3 #include "DlgProcess.h"
 4 #include "afxwin.h"
 5 // COVERVIEW 对话框
 6 
 7 class COVERVIEW : public CDialog
 8 {
 9     DECLARE_DYNAMIC(COVERVIEW)
10 
11 public:
12     COVERVIEW(CWnd* pParent = NULL);   // 标准构造函数
13     virtual ~COVERVIEW();
14 
15 // 对话框数据
16     enum { IDD = IDD_DIG_OVERVIEW };
17 
18 protected:
19     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
20     int CreatePyramids(const char* pszFileName, DlgProcess *pProgress);
21     DECLARE_MESSAGE_MAP()
22 public:
23     afx_msg void OnBnClickedBtnPath();
24     CEdit m_FileName;
25     CListBox listInfo;
26     int nLevelCount; 
27 };

OverView实现文件:

View Code
  1 // OVERVIEW.cpp : 实现文件
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "ImageInfo.h"
  6 #include "OVERVIEW.h"
  7 #include "afxdialogex.h"
  8 #include "cpl_conv.h"
  9 #include "gdal_priv.h"
 10 #include "DlgProcess.h"
 11 // COVERVIEW 对话框
 12 
 13 IMPLEMENT_DYNAMIC(COVERVIEW, CDialog)
 14 
 15 COVERVIEW::COVERVIEW(CWnd* pParent /*=NULL*/)
 16     : CDialog(COVERVIEW::IDD, pParent)
 17 {
 18     nLevelCount = 0;
 19 }
 20 
 21 COVERVIEW::~COVERVIEW()
 22 {
 23 }
 24 
 25 void COVERVIEW::DoDataExchange(CDataExchange* pDX)
 26 {
 27     CDialog::DoDataExchange(pDX);
 28     DDX_Control(pDX, IDC_EDIT_FILE3, m_FileName);
 29     DDX_Control(pDX, IDC_LIST1, listInfo);
 30 }
 31 
 32 
 33 BEGIN_MESSAGE_MAP(COVERVIEW, CDialog)
 34     ON_BN_CLICKED(IDC_BTN_PATH, &COVERVIEW::OnBnClickedBtnPath)
 35 END_MESSAGE_MAP()
 36 
 37 int CPL_STDCALL GDALProgress( double dfComplete, const char *pszMessage,   
 38     void * pProgressArg )  
 39 {  
 40     if(pProgressArg != NULL)  
 41     {  
 42         //CProcessBase * pProcess = (CProcessBase*) pProgressArg;      
 43         //DlgProcess* pDlgPro=(DlgProcess*)pProcess;
 44         DlgProcess* pProcess=(DlgProcess*)pProgressArg;
 45         pProcess->m_bIsContinue = pProcess->SetPosition(dfComplete);  
 46 
 47         if(pProcess->m_bIsContinue)  
 48             return TRUE;  
 49         else  
 50             return FALSE;  
 51     }  
 52     else  
 53         return TRUE;  
 54 
 55 }
 56 
 57 // COVERVIEW 消息处理程序
 58 
 59 int COVERVIEW:: CreatePyramids(const char* pszFileName, DlgProcess *pProgress)  
 60 {  
 61     if (pProgress != NULL)  
 62     {  
 63         pProgress->SetWindowTextA("创建金字塔");  
 64         pProgress->txtInfo.SetWindowTextA("正在创建金字塔...");  
 65     }  
 66 
 67     GDALAllRegister();  
 68     CPLSetConfigOption("USE_RRD","YES");    //创建Erdas格式的字塔文件   
 69     //      Open data file.                                           
 70 
 71     GDALDatasetH     hDataset;  
 72     hDataset = GDALOpen( pszFileName, GA_ReadOnly );  
 73 
 74     GDALDriverH hDriver = GDALGetDatasetDriver(hDataset);  
 75     const char* pszDriver = GDALGetDriverShortName(hDriver);  
 76     if (EQUAL(pszDriver, "HFA") || EQUAL(pszDriver, "PCIDSK"))  
 77     {  
 78         GDALClose(hDataset);    //如果文件是Erdas的img或者PCI的pix格式,创建内金字塔,其他的创建外金字塔   
 79         hDataset = GDALOpen( pszFileName, GA_ReadOnly );  
 80         //hDataset = GDALOpen( pszFileName, GA_Update );  
 81     }  
 82 
 83     if( hDataset == NULL )  
 84     {  
 85         if (pProgress != NULL)  
 86             pProgress->txtInfo.SetWindowTextA("打开图像失败,请检查图像是否存在或文件是否是图像文件!");  
 87 
 88         return RE_NOFILE;  
 89     }  
 90     //Get File basic infomation
 91     int iWidth = GDALGetRasterXSize(hDataset);  
 92     int iHeigh = GDALGetRasterYSize(hDataset);  
 93 
 94     int iPixelNum = iWidth * iHeigh;    //图像中的总像元个数   
 95     int iTopNum = 4096;                 //顶层金字塔大小,64*64   
 96     int iCurNum = iPixelNum / 4;  
 97 
 98     int anLevels[1024] = { 0 };  
 99                    //金字塔级数 
100 
101     do    //计算金字塔级数,从第二级到顶层
102     {  
103         anLevels[nLevelCount] = static_cast<int>(pow(2.0, nLevelCount+2));  
104         nLevelCount ++;  
105         iCurNum /= 4;  
106     } while (iCurNum > iTopNum);  
107 
108     const char *pszResampling = "nearest"; //采样方式
109     GDALProgressFunc pfnProgress = GDALProgress;//进度条
110 
111     /* -------------------------------------------------------------------- */  
112     /*      Generate overviews.                                             */  
113     /* -------------------------------------------------------------------- */  
114     if (nLevelCount > 0 &&  
115         GDALBuildOverviews( hDataset,pszResampling, nLevelCount, anLevels,  
116         0, NULL, pfnProgress, pProgress ) != CE_None )  
117     {  
118         if (pProgress != NULL)  
119             pProgress->txtInfo.SetWindowTextA("创建金字塔失败!");  
120 
121         return RE_FAILED;  
122     }  
123     /* -------------------------------------------------------------------- */  
124     /*      Cleanup                                                         */  
125     /* -------------------------------------------------------------------- */  
126     GDALClose(hDataset);  
127     GDALDestroyDriverManager();  
128 
129     if (pProgress != NULL)  
130         pProgress->txtInfo.SetWindowTextA("创建金字塔完成!");  
131 
132     return RE_SUCCESS;  
133 }  
134 
135 void COVERVIEW::OnBnClickedBtnPath()
136 {
137     CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("IMG影像文件(*.img)|*.img|TIFF影像文件(*.tiff)|*.tiff||"),AfxGetMainWnd());
138     CString str;
139     if (dlg.DoModal()==IDOK)
140     {
141         str=dlg.GetPathName();
142         const char* pszFile =(LPCTSTR)str;
143         m_FileName.SetWindowText(str);
144         DlgProcess *pProgress = new DlgProcess();  
145         pProgress->Create(IDD_Progress, this);    
146         pProgress->ShowWindow(SW_SHOW) ;
147         int f = CreatePyramids(pszFile, pProgress); 
148         CString strPyramidsInfo;
149         strPyramidsInfo.Append("重采样方式:nearest\n");
150         strPyramidsInfo.AppendFormat("采样层次:%d",nLevelCount);
151         listInfo.AddString(strPyramidsInfo);
152         delete pProgress;
153     }
154     // TODO: 在此添加控件通知处理程序代码
155 }

4.菜单调用的代码

1 void CImageInfoDlg::OnOverview()
2 {
3     // TODO: 在此添加命令处理程序代码
4     COVERVIEW dlgVec;
5     dlgVec.DoModal();
6 }

参考文献:

http://blog.csdn.net/liminlu0314/article/details/6127755 李民录博客推荐!

posted @ 2012-12-22 19:43  太一吾鱼水  阅读(1454)  评论(0编辑  收藏  举报