按照下面步骤,复制粘贴源码,可以建立一个图像处理窗口.
1.1 下载Visual Studio 2019并创建工程
参考以下文档:
[VS2019下载及MFC工程创建](file:///Users/biezikun/Downloads/VS2019安装及基本使用方法.pdf)
1.2 OpenCV版本选择及环境配置如果上面链接打不开,则参考老师发的Visual Studio安装文档,下载VS2019,安装最新的VS2022也可以,建议安装最新版本的。
按照老师发的文档成功创建一个MFC工程后直接运行可以出现一个空白窗口,如果没有请仔细检查.
建议选择3.4.14版本,环境配置参考以下博客,注意将博客中的 OpenCV版本修改为自己所下载的版本.
OpenCV环境配置
1.3 加入图像放大和缩小菜单OpenCV的环境配置也可以参考老师发的文档,注意最好下载3.4.14版本,否则后面的代码可能会报错.class="superseo">opencv下载网址
打开资源视图,打开菜单中的IDR…Type,在视图中添加“图像放大”和“图像缩小”属性, *** 作如图.
1.打开资源视图,在VS左上角视图中的其他视图里面,或者直接利用快捷键Ctrl+Shifr+E,选择图中以TYPE结尾的文件双击打开.
2.点击窗口中的视图,分别添加上图中的文字,然后先对图像放大进一步处理,再对图像缩小做相同处理.
3.注意:选择“图像放大”后,界面右下角会出现菜单编辑器,在其中找到“ID”修改为
ID_VIEW_ZOOM_OUT
,对于“图像缩小”的“ID”应改为ID_VIEW_ZOOM_IN
1.4 创建一个OpenCV菜单4.将图像放大缩小的ID均修改后,进行上图 *** 作.先选择“图像放大”鼠标右键,选择事件处理程序,类列表找到一View结尾的,消息类型和函数名与上图相同.对于“图像缩小”处理方法相同,不过函数名改为
OnViewZoomIn
.
重复1.3中的 *** 作,在“图像缩小”下面添加“OpenCV实例”,并在“OpenCV实例”下添加“OpenCV1”.
1.5 显示图像灰度配置和图像保存因为还没有进行OpenCV实例的实验,所以此处就先不用添加事件处理程序.
1.在界面右边打开类视图,或者使用快捷键Ctrl+Shift+C,选择View结尾的文件,鼠标右键选择类向导.
2.上图已经将所需步骤标记的很清楚了.注意选择的是View结尾的文件
3. *** 作同上,注意选择的是Doc结尾的文件.图中加粗的表示我添加的函数,如果你的对应函数没有加粗,说明创建工程时步骤不正确,建议重开.当然也可以手动把图中函数添加.
1.6 各个文件的代码
1.6.1 头文件的代码下面是各个文件的代码,你可以选择参考,也可以直接复制粘贴.不过需要注意的是,复制粘贴需要用查找替换(Ctrl+F)将每个文件中的
BieZiKun
替换成你自己的名字.按照下图目录依次写出的代码如下所示.
-
BieZiKunImage.h
// BieZiKunImage.h: BieZiKunImage 应用程序的主头文件 #pragma once #ifndef __AFXWIN_H__ #error "在包含此文件之前包含 'pch.h' 以生成 PCH" #endif #include "resource.h" // 主符号 // CBieZiKunImageApp: // 有关此类的实现,请参阅 BieZiKunImage.cpp // class CBieZiKunImageApp : public CWinApp { public: CBieZiKunImageApp() noexcept; // 重写 public: virtual BOOL InitInstance(); virtual int ExitInstance(); // 实现 afx_msg void OnAppAbout(); DECLARE_MESSAGE_MAP() }; extern CBieZiKunImageApp theApp;
-
BieZiKunImageDoc.h
// BieZiKunImageDoc.h: CBieZiKunImageDoc 类的接口 #pragma once #include
#include #include #include //#include #include class CBieZiKunImageDoc : public CDocument { protected: // 仅从序列化创建 CBieZiKunImageDoc(); DECLARE_DYNCREATE(CBieZiKunImageDoc); // 特性 public: IplImage* image; BITMAPINFO* lpbmi; unsigned char* m_pBits; BITMAPFILEHEADER bmpFH; int imageWidth; int imageHeight; int m_nColorBits;//8 24 int m_nOpenMode;//=0 RAW=1 BMP=2 OpenCV virtual ~CBieZiKunImageDoc(); // *** 作 public: void ReadRAW(LPCTSTR lpszPathName, int nWidth, int nHeight); BOOL ReadBMP(LPCTSTR lpszPathName); BOOL SaveBMP(LPCTSTR lpszPathName); //BOOL OnOpenDocument(LPCTSTR lpszPathName); // 重写 public: virtual BOOL OnNewDocument(); virtual void Serialize(CArchive& ar); #ifdef SHARED_HANDLERS virtual void InitializeSearchContent(); virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds); #endif // SHARED_HANDLERS // 实现 public: //virtual ~CBieZiKunImageDoc(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; BOOL OnOpenDocument(LPCTSTR lpszPathName); #endif protected: // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() #ifdef SHARED_HANDLERS // 用于为搜索处理程序设置搜索内容的 Helper 函数 void SetSearchContent(const CString& value); #endif // SHARED_HANDLERS public: virtual BOOL OnSaveDocument(LPCTSTR lpszPathName); }; -
BieZiKunImageView.h
// BieZiKunImageView.h: CBieZiKunImageView 类的接口 #pragma once class CBieZiKunImageView : public CScrollView { protected: // 仅从序列化创建 double m_dZoom; CBieZiKunImageView() noexcept; DECLARE_DYNCREATE(CBieZiKunImageView) // 特性 public: CBieZiKunImageDoc* GetDocument() const; // *** 作 public: // 重写 public: virtual void OnDraw(CDC* pDC); // 重写以绘制该视图 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual void OnInitialUpdate(); // 构造后第一次调用 virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); // 实现 public: virtual ~CBieZiKunImageView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnViewZoomOut(); afx_msg void OnViewZoomIn(); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnOpencv1(); afx_msg void OnOnopenCV1(); afx_msg void OnOnopencv1(); }; #ifndef _DEBUG // BieZiKunImageView.cpp 中的调试版本 inline CBieZiKunImageDoc* CBieZiKunImageView::GetDocument() const { return reinterpret_cast
(m_pDocument); } #endif -
ChildFrm.h
// ChildFrm.h: CChildFrame 类的接口 #pragma once class CChildFrame : public CMDIChildWnd { DECLARE_DYNCREATE(CChildFrame) public: CChildFrame() noexcept; // 特性 protected: CSplitterWnd m_wndSplitter; public: // *** 作 public: // 重写 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); // 实现 public: virtual ~CChildFrame(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() };
-
framework.h
#pragma once #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 #endif #include "targetver.h" #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的 // 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息 #define _AFX_ALL_WARNINGS #include // MFC 核心组件和标准组件 #include // MFC 扩展 #include // MFC 自动化类 #ifndef _AFX_NO_OLE_SUPPORT #include // MFC 对 Internet Explorer 4 公共控件的支持 #endif #ifndef _AFX_NO_AFXCMN_SUPPORT #include // MFC 对 Windows 公共控件的支持 #endif // _AFX_NO_AFXCMN_SUPPORT #include // MFC 支持功能区和控制条 #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #endif
-
MainFrm.h
// MainFrm.h: CMainFrame 类的接口 // #pragma once class CMainFrame : public CMDIFrameWnd { DECLARE_DYNAMIC(CMainFrame) public: CMainFrame() noexcept; // 特性 public: // *** 作 public: // 重写 public: virtual BOOL PreCreateWindow(CREATESTRUCT& cs); // 实现 public: virtual ~CMainFrame(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif void SetStatusBarText(int nIndex, CString strText); protected: // 控件条嵌入成员 CToolBar m_wndToolBar; CStatusBar m_wndStatusBar; // 生成的消息映射函数 protected: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); DECLARE_MESSAGE_MAP() };
-
pch.h
// pch.h: 这是预编译标头文件。 // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 #ifndef PCH_H #define PCH_H // 添加要在此处预编译的标头 #include "framework.h" #endif //PCH_H
-
Resource.h
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 BieZiKunImage.rc 使用 // #define IDD_ABOUTBOX 100 #define IDP_OLE_INIT_FAILED 100 #define IDR_MAINFRAME 128 #define IDR_BieZiKunImageTYPE 130 #define ID_WINDOW_MANAGER 131 #define ID_32771 32771 #define ID_32772 32772 #define ID_VIEW_ZOOM_OUT 32773 #define ID_VIEW_ZOOM_IN 32774 #define ID_32775 32775 #define ID_OPENCV32776 32776 #define ID_OnOpencv1 32777 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 310 #define _APS_NEXT_COMMAND_VALUE 32778 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 310 #endif #endif
-
targetver.h
#pragma once // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 //如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并 // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 #include
-
BieZiKunImage.cpp
// BieZiKunImage.cpp: 定义应用程序的类行为。 // #include "pch.h" #include "framework.h" #include "afxwinappex.h" #include "afxdialogex.h" #include "BieZiKunImage.h" #include "MainFrm.h" #include "ChildFrm.h" #include "BieZiKunImageDoc.h" #include "BieZiKunImageView.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CBieZiKunImageApp BEGIN_MESSAGE_MAP(CBieZiKunImageApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, &CBieZiKunImageApp::OnAppAbout) // 基于文件的标准文档命令 ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen) // 标准打印设置命令 ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup) END_MESSAGE_MAP() // CBieZiKunImageApp 构造 CBieZiKunImageApp::CBieZiKunImageApp() noexcept { // 支持重新启动管理器 m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS; #ifdef _MANAGED // 如果应用程序是利用公共语言运行时支持(/clr)构建的,则: // 1) 必须有此附加设置,“重新启动管理器”支持才能正常工作。 // 2) 在您的项目中,您必须按照生成顺序向 System.Windows.Forms 添加引用。 System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException); #endif // TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式 //为 CompanyName.ProductName.SubProduct.VersionInformation SetAppID(_T("BieZiKunImage.AppID.NoVersion")); // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 } // 唯一的 CBieZiKunImageApp 对象 CBieZiKunImageApp theApp; // CBieZiKunImageApp 初始化 BOOL CBieZiKunImageApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。 否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); // 初始化 OLE 库 if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } AfxEnableControlContainer(); EnableTaskbarInteraction(FALSE); // 使用 RichEdit 控件需要 AfxInitRichEdit2() // AfxInitRichEdit2(); // 标准初始化 // 如果未使用这些功能并希望减小 // 最终可执行文件的大小,则应移除下列 // 不需要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当修改该字符串, // 例如修改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU) // 注册应用程序的文档模板。 文档模板 // 将用作文档、框架窗口和视图之间的连接 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_BieZiKunImageTYPE, RUNTIME_CLASS(CBieZiKunImageDoc), RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(CBieZiKunImageView)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); // 创建主 MDI 框架窗口 CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) { delete pMainFrame; return FALSE; } m_pMainWnd = pMainFrame; // 分析标准 shell 命令、DDE、打开文件 *** 作的命令行 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // 调度在命令行中指定的命令。 如果 // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。 if (!ProcessShellCommand(cmdInfo)) return FALSE; // 主窗口已初始化,因此显示它并对其进行更新 pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); return TRUE; } int CBieZiKunImageApp::ExitInstance() { //TODO: 处理可能已添加的附加资源 AfxOleTerm(FALSE); return CWinApp::ExitInstance(); } // CBieZiKunImageApp 消息处理程序 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg() noexcept; // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // 用于运行对话框的应用程序命令 void CBieZiKunImageApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } // CBieZiKunImageApp 消息处理程序
-
BieZiKunImageDoc.cpp
// BieZiKunImageDoc.cpp: CBieZiKunImageDoc 类的实现 // #include "pch.h" #include "framework.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "BieZiKunImage.h" #endif #include "BieZiKunImageDoc.h" #include
#ifdef _DEBUG #define new DEBUG_NEW #endif // CBieZiKunImageDoc IMPLEMENT_DYNCREATE(CBieZiKunImageDoc, CDocument) BEGIN_MESSAGE_MAP(CBieZiKunImageDoc, CDocument) END_MESSAGE_MAP() // CBieZiKunImageDoc 构造/析构 CBieZiKunImageDoc::CBieZiKunImageDoc() { // TODO: 在此添加一次性构造代码 m_pBits = NULL; lpbmi=NULL; imageWidth = 768; imageHeight = 576; m_nOpenMode = 0; m_nColorBits = 8; image = NULL; } CBieZiKunImageDoc::~CBieZiKunImageDoc() { } BOOL CBieZiKunImageDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: 在此添加重新初始化代码 // (SDI 文档将重用该文档) return TRUE; } // CBieZiKunImageDoc 序列化 void CBieZiKunImageDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: 在此添加存储代码 } else { // TODO: 在此添加加载代码 } } #ifdef SHARED_HANDLERS // 缩略图的支持 void CBieZiKunImageDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds) { // 修改此代码以绘制文档数据 dc.FillSolidRect(lprcBounds, RGB(255, 255, 255)); CString strText = _T("TODO: implement thumbnail drawing here"); LOGFONT lf; CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)); pDefaultGUIFont->GetLogFont(&lf); lf.lfHeight = 36; CFont fontDraw; fontDraw.CreateFontIndirect(&lf); CFont* pOldFont = dc.SelectObject(&fontDraw); dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK); dc.SelectObject(pOldFont); } // 搜索处理程序的支持 void CBieZiKunImageDoc::InitializeSearchContent() { CString strSearchContent; // 从文档数据设置搜索内容。 // 内容部分应由“;”分隔 // 例如: strSearchContent = _T("point;rectangle;circle;ole object;"); SetSearchContent(strSearchContent); } void CBieZiKunImageDoc::SetSearchContent(const CString& value) { if (value.IsEmpty()) { RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid); } else { CMFCFilterChunkValueImpl *pChunk = nullptr; ATLTRY(pChunk = new CMFCFilterChunkValueImpl); if (pChunk != nullptr) { pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT); SetChunkValue(pChunk); } } } #endif // SHARED_HANDLERS // CBieZiKunImageDoc 诊断 #ifdef _DEBUG void CBieZiKunImageDoc::AssertValid() const { CDocument::AssertValid(); } void CBieZiKunImageDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG // CBieZiKunImageDoc 命令 BOOL CBieZiKunImageDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; CString str = lpszPathName; str.MakeLower(); if (str.Find(TEXT(".bmp")) != -1) { m_nOpenMode = 1; if (!ReadBMP(lpszPathName))return FALSE; } if (str.Find(_TEXT(".jpg")) != -1) { m_nOpenMode = 2; image = (cvLoadImage((CStringA)lpszPathName)); lpbmi = (LPBITMAPINFO)new char[sizeof(BITMAPCOREINFO) + 4 * (1 << 8)]; lpbmi->bmiHeader.biBitCount = image->depth * image->nChannels; lpbmi->bmiHeader.biClrUsed = 0; lpbmi->bmiHeader.biHeight = image->height; lpbmi->bmiHeader.biWidth = image->width; lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbmi->bmiHeader.biSizeImage = image->width * image->height * image->nChannels; lpbmi->bmiHeader.biClrImportant = 0; lpbmi->bmiHeader.biCompression = 0; lpbmi->bmiHeader.biPlanes = 1; imageWidth = image->width; imageHeight = image->height; for (int i = 0; i < (1 << 8); i++) { RGBQUAD& o = lpbmi->bmiColors[1]; o.rgbBlue = i; o.rgbGreen = i; o.rgbRed = i; o.rgbReserved = 0; } } return TRUE; } BOOL CBieZiKunImageDoc::ReadBMP(LPCTSTR lpszPathName) { long lTotal = 0; CFile file; file.Open(lpszPathName, CFile::modeRead); file.Read(&bmpFH, sizeof(BITMAPFILEHEADER)); lpbmi = (LPBITMAPINFO)new char[sizeof(BITMAPINFO) + 4 * (1 << 8)]; /*lpbmi->bmiHeader.biBitCount=8; lpbmi->bmiHeader.biClrUsed=0; lpbmi->bmiHeader.biHeight=imageHeight; lpbmi->bmiHeader.biWidth=imageWidth; lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbmi->bmiHeader.biSizeImage = imageWidth * imageHeight; lpbmi->bmiHeader.biClrImportant = 0; lpbmi->bmiHeader.biCompression = 0; lpbmi->bmiHeader.biPlanes = 1; lpbmi->bmiColors[i];*/ file.Read(lpbmi,sizeof(BITMAPINFOHEADER)); m_nColorBits = lpbmi->bmiHeader.biBitCount; imageHeight = lpbmi->bmiHeader.biHeight; imageWidth = lpbmi->bmiHeader.biWidth; if (m_nColorBits == 8) { lTotal = imageWidth * imageHeight; file.Read(&lpbmi->bmiColors[0], 256 * 4); } else if (m_nColorBits == 24) { lTotal = imageWidth * imageHeight * 3; } else { file.Close(); return FALSE; } m_pBits = new unsigned char[lTotal]; file.Read(m_pBits, lTotal); file.Close(); return TRUE; } BOOL CBieZiKunImageDoc::SaveBMP(LPCTSTR lpszPathName) { long lTotal = 0; CFile file; file.Open(lpszPathName, CFile::modeCreate | CFile::modeReadWrite); file.Write(&bmpFH, sizeof(BITMAPFILEHEADER)); file.Write(lpbmi, sizeof(BITMAPFILEHEADER)); if (m_nColorBits == 8) { lTotal = imageWidth * imageHeight; file.Write(&lpbmi->bmiColors[0], 256 * 4); } else if (m_nColorBits == 24) { lTotal = imageWidth * imageHeight * 3; } else { file.Close(); return FALSE; } file.Write(m_pBits, lTotal); file.Close(); return TRUE; } BOOL CBieZiKunImageDoc::OnSaveDocument(LPCTSTR lpszPathName) { // TODO: 在此添加专用代码和/或调用基类 if (m_nOpenMode == 1 && m_pBits != NULL) SaveBMP(lpszPathName); if (m_nOpenMode == 2 && image != NULL) { cvSaveImage((CStringA)lpszPathName, image); } return TRUE; return CDocument::OnSaveDocument(lpszPathName); } -
BieZiKunImageView.cpp
// BieZiKunImageView.cpp: CBieZiKunImageView 类的实现 // #include "pch.h" #include "framework.h" #include"MainFrm.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "BieZiKunImage.h" #endif #include "BieZiKunImageDoc.h" #include "BieZiKunImageView.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CBieZiKunImageView IMPLEMENT_DYNCREATE(CBieZiKunImageView, CScrollView) BEGIN_MESSAGE_MAP(CBieZiKunImageView, CScrollView) // 标准打印命令 ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CScrollView::OnFilePrintPreview) ON_COMMAND(ID_VIEW_ZOOM_OUT, &CBieZiKunImageView::OnViewZoomOut) ON_COMMAND(ID_VIEW_ZOOM_IN, &CBieZiKunImageView::OnViewZoomIn) ON_WM_MOUSEMOVE() END_MESSAGE_MAP() // CBieZiKunImageView 构造/析构 CBieZiKunImageView::CBieZiKunImageView() noexcept { // TODO: 在此处添加构造代码 m_dZoom = 1.0; } CBieZiKunImageView::~CBieZiKunImageView() { } BOOL CBieZiKunImageView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return CScrollView::PreCreateWindow(cs); } // CBieZiKunImageView 绘图 void CBieZiKunImageView::OnDraw(CDC* pDC) { CBieZiKunImageDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; CSize sizeTotal; sizeTotal.cx = int(m_dZoom * pDoc->imageWidth + 0.5); sizeTotal.cy = int(m_dZoom * pDoc->imageHeight + 0.5); SetScrollSizes(MM_TEXT, sizeTotal); // TODO: 在此处为本机数据添加绘制代码 if (pDoc->m_nOpenMode == 1)//BMP { StretchDIBits(pDC->m_hDC, 0, 0, int(m_dZoom*pDoc->imageWidth+0.5),int(m_dZoom*pDoc->imageHeight+0.5),0,0,pDoc->imageWidth,pDoc->imageHeight,pDoc->m_pBits, pDoc->lpbmi, DIB_RGB_COLORS, SRCCOPY); } if (pDoc->m_nOpenMode == 2)//JPG { StretchDIBits(pDC->m_hDC, 0, 0, int(m_dZoom * pDoc->image->width+0.5), int(m_dZoom * pDoc->image->height+0.5),0, pDoc->image->height, pDoc->image->width, -pDoc->image->height, pDoc->image->imageData, pDoc->lpbmi, DIB_RGB_COLORS, SRCCOPY); } } void CBieZiKunImageView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal; // TODO: 计算此视图的合计大小 sizeTotal.cx = sizeTotal.cy = 100; SetScrollSizes(MM_TEXT, sizeTotal); } // CBieZiKunImageView 打印 BOOL CBieZiKunImageView::OnPreparePrinting(CPrintInfo* pInfo) { // 默认准备 return DoPreparePrinting(pInfo); } void CBieZiKunImageView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加额外的打印前进行的初始化过程 } void CBieZiKunImageView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加打印后进行的清理过程 } // CBieZiKunImageView 诊断 #ifdef _DEBUG void CBieZiKunImageView::AssertValid() const { CScrollView::AssertValid(); } void CBieZiKunImageView::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); } CBieZiKunImageDoc* CBieZiKunImageView::GetDocument() const // 非调试版本是内联的 { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBieZiKunImageDoc))); return (CBieZiKunImageDoc*)m_pDocument; } #endif //_DEBUG // CBieZiKunImageView 消息处理程序 void CBieZiKunImageView::OnViewZoomOut() { // TODO: 在此添加命令处理程序代码 m_dZoom = m_dZoom * 2; Invalidate(); } void CBieZiKunImageView::OnViewZoomIn() { // TODO: 在此添加命令处理程序代码 m_dZoom = m_dZoom / 2; Invalidate(); } void CBieZiKunImageView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CBieZiKunImageDoc* pDoc = GetDocument(); if (pDoc->m_pBits != NULL || pDoc->image != NULL) { CPoint scrPoint = GetScrollPosition(); int nX = int(0.5 + (scrPoint.x + point.x) / m_dZoom); int nY = int(0.5 + (scrPoint.y + point.y) / m_dZoom); int nR, nG, nB; if (nX >= 0 && nX < pDoc->imageWidth && nY>=0 && nY < pDoc->imageHeight) { CString strPrompt; if (pDoc->m_nOpenMode == 1)//BMP { if (pDoc->m_nColorBits==8)//gray image { nB = *(pDoc->m_pBits + (pDoc->imageHeight - nY - 1) * pDoc->imageWidth + nX); strPrompt.Format(_T("X:%4d-Y:%4d Gray:%3d"), nX, nY, nB); } if (pDoc->m_nColorBits == 24)//color image { nB = *(pDoc->m_pBits + (pDoc->imageHeight - nY - 1) * pDoc->imageWidth * 3 + nX * 3 + 0); nG = *(pDoc->m_pBits + (pDoc->imageHeight - nY - 1) * pDoc->imageWidth * 3 + nX * 3 + 1); nR = *(pDoc->m_pBits + (pDoc->imageHeight - nY - 1) * pDoc->imageWidth * 3 + nX * 3 + 2); strPrompt.Format(_T("X:%4d-Y:%4d R:%3d G:%3d B:%3d"), nX, nY, nR,nG,nB); } } if (pDoc->m_nOpenMode == 2)//JPG { pDoc->m_pBits = (unsigned char*)pDoc->image->imageData; if (pDoc->image->nChannels==1)//gray image { nB = *(pDoc->m_pBits +nY*pDoc->imageWidth+ nX); strPrompt.Format(_T("X:%4d-Y:%4d Gray:%3d"), nX, nY, nB); } if (pDoc->image->nChannels==3)//color image { nB = *(pDoc->m_pBits + nY * pDoc->imageWidth * 3 + nX * 3 + 0); nG = *(pDoc->m_pBits + nY * pDoc->imageWidth * 3 + nX * 3 + 1); nR = *(pDoc->m_pBits + nY * pDoc->imageWidth * 3 + nX * 3 + 2); strPrompt.Format(_T("X:%4d-Y:%4d R:%3d G:%3d B:%3d"), nX, nY, nR, nG, nB); } } ((CMainFrame*)AfxGetMainWnd())->SetStatusBarText(1, strPrompt); } } CScrollView::OnMouseMove(nFlags, point); } void CBieZiKunImageView::OnOpencv1() { int nRetCode = 0; CvPoint center; double scale = -3; CBieZiKunImageDoc* pDoc = GetDocument(); IplImage* image = pDoc->image; if (!image)return; cvNamedWindow("test0", 1); cvShowImage("test0", image); center = cvPoint(image->width / 2, image->height / 2); for (int i = 0; i < image->height; i++) { for (int j = 0; j < image->width; j++) { double dx = (double)(j - center.x) / center.x; double dy = (double)(j - center.y) / center.y; double weight = exp((dx * dx + dy * dy) * scale); uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3); ptr[0] = cvRound(ptr[0] * weight); ptr[1] = cvRound(ptr[1] * weight); ptr[2] = cvRound(ptr[2] * weight); } } cvSaveImage("d:\\Copy.jpg", image); cvNamedWindow("test", 1); cvShowImage("test", image); cvWaitKey(); }
-
ChildFrm.cpp
// ChildFrm.cpp: CChildFrame 类的实现 // #include "pch.h" #include "framework.h" #include "BieZiKunImage.h" #include "ChildFrm.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CChildFrame IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd) BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd) END_MESSAGE_MAP() // CChildFrame 构造/析构 CChildFrame::CChildFrame() noexcept { // TODO: 在此添加成员初始化代码 } CChildFrame::~CChildFrame() { } BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或样式 if( !CMDIChildWnd::PreCreateWindow(cs) ) return FALSE; return TRUE; } // CChildFrame 诊断 #ifdef _DEBUG void CChildFrame::AssertValid() const { CMDIChildWnd::AssertValid(); } void CChildFrame::Dump(CDumpContext& dc) const { CMDIChildWnd::Dump(dc); } #endif //_DEBUG // CChildFrame 消息处理程序
-
MainFrm.cpp
// MainFrm.cpp: CMainFrame 类的实现 // #include "pch.h" #include "framework.h" #include "BieZiKunImage.h" #include "MainFrm.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CMainFrame IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_WM_CREATE() END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, ID_SEPARATOR, // 状态行指示器 ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; // CMainFrame 构造/析构 CMainFrame::CMainFrame() noexcept { // TODO: 在此添加成员初始化代码 } CMainFrame::~CMainFrame() { } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("未能创建工具栏\n"); return -1; // 未能创建 } if (!m_wndStatusBar.Create(this)) { TRACE0("未能创建状态栏\n"); return -1; // 未能创建 } m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)); // TODO: 如果不需要可停靠工具栏,则删除这三行 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CMDIFrameWnd::PreCreateWindow(cs) ) return FALSE; // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return TRUE; } // CMainFrame 诊断 #ifdef _DEBUG void CMainFrame::AssertValid() const { CMDIFrameWnd::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CMDIFrameWnd::Dump(dc); } void CMainFrame::SetStatusBarText(int nIndex, CString strText) { m_wndStatusBar.SetPaneText(nIndex, strText); } #endif //_DEBUG // CMainFrame 消息处理程序
-
pch.cpp
// pch.cpp: 与预编译标头对应的源文件 #include "pch.h" // 当使用预编译的头时,需要使用此源文件,编译才能成功。
到此总算是结束了所有内容,制作不易,仅供学习交流.对于老师发的文件,很多且很杂,理清楚要花不少时间,正是经历了那些奇奇怪怪的Bug才让我打算写一篇系统一点的文字记录一下,同时也帮助后面学的同学快速搭建起相关环境,以便后面的学习.当然如果你觉得上面的内容也很多,不想一个一个复制,可以下方评论我私发
文件给你.
再次注意: 在自己的工程中一定要查找替换BieZiKun
,改成自己名字.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)