今天又考了一次六级,不知道结果怎么样!
贴出昨天的工作,采用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 (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 }
参考文献:
博客推荐!