数字图像处理笔记

数字图像处理笔记,第1张

数字图像处理笔记 1.基于Visual Studio 2019及OpenCV3.4.14的环境配置

按照下面步骤,复制粘贴源码,可以建立一个图像处理窗口.


1.1 下载Visual Studio 2019并创建工程

参考以下文档:
[VS2019下载及MFC工程创建](file:///Users/biezikun/Downloads/VS2019安装及基本使用方法.pdf)

如果上面链接打不开,则参考老师发的Visual Studio安装文档,下载VS2019,安装最新的VS2022也可以,建议安装最新版本的。
按照老师发的文档成功创建一个MFC工程后直接运行可以出现一个空白窗口,如果没有请仔细检查.

1.2 OpenCV版本选择及环境配置

建议选择3.4.14版本,环境配置参考以下博客,注意将博客中的 OpenCV版本修改为自己所下载的版本.
OpenCV环境配置

OpenCV的环境配置也可以参考老师发的文档,注意最好下载3.4.14版本,否则后面的代码可能会报错.class="superseo">opencv下载网址

1.3 加入图像放大和缩小菜单

打开资源视图,打开菜单中的IDR…Type,在视图中添加“图像放大”和“图像缩小”属性, *** 作如图.

1.打开资源视图,在VS左上角视图中的其他视图里面,或者直接利用快捷键Ctrl+Shifr+E,选择图中以TYPE结尾的文件双击打开.


2.点击窗口中的视图,分别添加上图中的文字,然后先对图像放大进一步处理,再对图像缩小做相同处理.


3.注意:选择“图像放大”后,界面右下角会出现菜单编辑器,在其中找到“ID”修改为ID_VIEW_ZOOM_OUT,对于“图像缩小”的“ID”应改为ID_VIEW_ZOOM_IN


4.将图像放大缩小的ID均修改后,进行上图 *** 作.先选择“图像放大”鼠标右键,选择事件处理程序,类列表找到一View结尾的,消息类型和函数名与上图相同.对于“图像缩小”处理方法相同,不过函数名改为OnViewZoomIn.

1.4 创建一个OpenCV菜单

重复1.3中的 *** 作,在“图像缩小”下面添加“OpenCV实例”,并在“OpenCV实例”下添加“OpenCV1”.

因为还没有进行OpenCV实例的实验,所以此处就先不用添加事件处理程序.

1.5 显示图像灰度配置和图像保存

1.在界面右边打开类视图,或者使用快捷键Ctrl+Shift+C,选择View结尾的文件,鼠标右键选择类向导.


2.上图已经将所需步骤标记的很清楚了.注意选择的是View结尾的文件


3. *** 作同上,注意选择的是Doc结尾的文件.图中加粗的表示我添加的函数,如果你的对应函数没有加粗,说明创建工程时步骤不正确,建议重开.当然也可以手动把图中函数添加.


1.6 各个文件的代码

下面是各个文件的代码,你可以选择参考,也可以直接复制粘贴.不过需要注意的是,复制粘贴需要用查找替换(Ctrl+F)将每个文件中的BieZiKun替换成你自己的名字.按照下图目录依次写出的代码如下所示.

1.6.1 头文件的代码
  1. 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;
    
  2. 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);
    };
    
  3. 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
    
  4. 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()
    };
    
  5. 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
    
  6. 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()
    };
    
  7. pch.h

    // pch.h: 这是预编译标头文件。
    // 下方列出的文件仅编译一次,提高了将来生成的生成性能。
    // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
    // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
    // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
    
    #ifndef PCH_H
    #define PCH_H
    
    // 添加要在此处预编译的标头
    #include "framework.h"
    
    #endif //PCH_H
    
  8. 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
    
  9. targetver.h

    #pragma once
    
    // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
    
    //如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并
    // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
    
    #include 
    
1.6.2 源文件的代码
  1. 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 消息处理程序
    
  2. 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);
    }
    
  3. 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();
    }
    
  4. 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 消息处理程序
    
  5. 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 消息处理程序
    
  6. pch.cpp

    // pch.cpp: 与预编译标头对应的源文件
    
    #include "pch.h"
    
    // 当使用预编译的头时,需要使用此源文件,编译才能成功。
    
1.7 结语

到此总算是结束了所有内容,制作不易,仅供学习交流.对于老师发的文件,很多且很杂,理清楚要花不少时间,正是经历了那些奇奇怪怪的Bug才让我打算写一篇系统一点的文字记录一下,同时也帮助后面学的同学快速搭建起相关环境,以便后面的学习.当然如果你觉得上面的内容也很多,不想一个一个复制,可以下方评论我私发
文件给你.
再次注意: 在自己的工程中一定要查找替换BieZiKun,改成自己名字.

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/2991661.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存