MFC读取图片方式

1.类型:HBITMAP、CBitmap、CImage、Mat(Open cv)、HObject(Halcon)
2.注意图像单通道与三通道的问题
3.实现类

// Bmp.h : 获取bmp图片头文件
//

#pragma once

#include<vector>
#include"highgui.h"
#include "HalconCpp.h"

using namespace std;
using namespace cv;
using namespace HalconCpp;

class CBmp
{
//单例模式
private:  
    CBmp(CString* dir, int length);//构造函数  
    CBmp(const CBmp &);  
    CBmp& operator = (const CBmp &);  
public:  
    static CBmp *Instantialize(CString* dir, int length);  
    static CBmp *pInstance;  
//-----------------------------------------------------------------------
public:
    ~CBmp(void);

    //成员变量
    CBitmap m_bitmap;                                       //创建位图对象
    CImage  m_image;                                        //创建CImage
    Mat m_mat;                                              //创建opencv Mat
    HObject m_object;                                       //创建Halcon HObject

    //成员函数
    void GetPic(int type);                                  //获取图片
    void ShowPic(CWnd *pWnd);                               //用来显示指定图片的函数
    void TraverseDir(CString& dir, vector<CString>& vec);   //获取文件夹所有路径
    bool HBitmapToMat(HBITMAP& _hBmp,Mat& _mat);            //HBitmapToMat转换
    void MatToCImage(Mat& mat, CImage& cimage);             //MatToCImage转换
    void CImageToMat(CImage& cimage, Mat& mat);             //CImageToMat转换
    void dev_open_window_fit_image (HObject ho_Image, HTuple hv_Row, HTuple hv_Column, 
        HTuple hv_WidthLimit, HTuple hv_HeightLimit, HTuple *hv_WindowHandle);//独立窗口显示HObject图片

    CWnd            *m_pWnd;                                ///< 显示图像窗口(控件)指针
    HDC             m_hDC;                                  ///< 绘制图像DC句柄
    vector<CString> *paths;                                 //存储文件夹所有图片路径
    int             *index;                                 //图片路径标识
};
// Bmp.cpp : 获取bmp图片实现类
//

#include "stdAfx.h"
#include "Bmp.h"
#include "MyNewDlg.h "

//指针赋0,就是不指向任何对象,相当于NULL
CBmp* CBmp::pInstance = 0;  

CBmp* CBmp::Instantialize(CString* dir, int length)  
{  
    if(pInstance == NULL)  
    {  
        pInstance = new CBmp(dir, length);  
    }  
    return pInstance;  
} 

CBmp::CBmp(CString* dir, int length)
    : index(new int[length]),
    paths(new vector<CString>[length])
{
    for(int i=0;i<length; i++)
    {
        //获取文件夹下所有文件路径paths
        TraverseDir(dir[i], paths[i]);
        index[i] = 0;
    }
}


CBmp::~CBmp(void)
{
    CBmp::pInstance = 0;  
}

void CBmp::GetPic(int type)
{
    //最后一张图片提示
    if(index[type] == paths[type].size())
    {
        index[type] = 0;
        //MessageBox会暂时终止程序执行
        //MessageBox(NULL,_T("最后一张图片,重新开始"),_T("提示"),MB_OK);
        //自定义对话框不会暂时终止程序执行
         CMyNewDlg  *pDlg=new CMyNewDlg ;
         pDlg->Create(IDD_DIALOG_WA);
         pDlg->ShowWindow(SW_SHOW);
    }

    //定义bitmap指针 调用函数LoadImage装载位图
    HBITMAP m_hBitmap;
    m_hBitmap = (HBITMAP) LoadImage(NULL,paths[type][index[type]],IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);

    /*************************************************************************/
    /* 1.要装载OEM图像,则设此参数值为0  OBM_ OEM位图 OIC_OEM图标 OCR_OEM光标
    /* 2.BmpName要装载图片的文件名                  
    /* 3.装载图像类型: 
    /*   IMAGE_BITMAP-装载位图 IMAGE_CURSOR-装载光标 IMAGE_ICON-装载图标    
    /* 4.指定图标或光标的像素宽度和长度 以像素为单位    
    /* 5.加载选项:
    /*   IR_LOADFROMFILE-指明由lpszName指定文件中加载图像
    /*   IR_DEFAULTSIZE-指明使用图像默认大小
    /*   LR_CREATEDIBSECTION-当uType参数为IMAGE_BITMAP时,创建一个DIB项
    /**************************************************************************/

    //CBitmap
    if( m_bitmap.m_hObject )
    {
        m_bitmap.Detach();           //切断CWnd和窗口联系
    }
    m_bitmap.Attach(m_hBitmap);      //将句柄HBITMAP m_hBitmap与CBitmap m_bitmap关联

    //CImage
    if(!m_image.IsNull())            //Attach与Load前,必须确认img中无位图,否则会弹出异常,但忽略也可继续运行
        m_image.Destroy();
    //m_image.Attach(m_hBitmap);
    m_image.Load(paths[type][index[type]]); 

    //Mat
    //HBitmapToMat(m_hBitmap, m_mat);
    USES_CONVERSION;
    //m_mat = imread(W2A(paths[type][index[type]]));
    CImageToMat(m_image, m_mat);

    //HObject(Unicode下 CString->char*)
    //1
    _bstr_t bstrVar(paths[type][index[type]]); 
    char *ch = bstrVar;
    //2
    CString str1 = paths[type][index[type]]; 
    //int len =WideCharToMultiByte(CP_ACP,0,str1,-1,NULL,0,NULL,NULL);  
    //char *ptxtTemp =new char[len +1];  
    //WideCharToMultiByte(CP_ACP,0,str1,-1,ptxtTemp,len,NULL,NULL ); 
    //ReadImage(&m_object, ptxtTemp);
    //3
    char *ptxtTemp = W2A(str1);  
    TRACE(ptxtTemp);
    ReadImage(&m_object, ptxtTemp);


    index[type]++;
}

void CBmp::ShowPic(CWnd *pWnd)
{
    //获取图像显示窗口的指针和绘图DC句柄
    m_pWnd = pWnd;
    m_hDC  = ::GetDC(m_pWnd->m_hWnd);  

    MatToCImage(m_mat, m_image);
    //pWnd->ModifyStyle(0, SS_BITMAP);              //修改它的属性为位图 
    //((CStatic*)m_pWnd)->SetBitmap(m_bitmap);      //显示CBitmap图片
    ((CStatic*)m_pWnd)->SetBitmap(m_image);     //显示CImage图片

    //该方式显示静态图片,并不能刷新
    //HTuple width, height;
    //GetImageSize(m_object, &height, &width);
    //HWND hImgWnd = m_pWnd->m_hWnd; 
    //CRect rtWindow;
    //m_pWnd->GetClientRect(&rtWindow);
    //HTuple m_htWindow;
    //OpenWindow(rtWindow.left, rtWindow.top, rtWindow.Width(), rtWindow.Height(), (Hlong)hImgWnd, "visible", "", &m_htWindow);
    //SetPart(m_htWindow, 0, 0, width, height);
    //DispObj(m_object, m_htWindow);
    //pWnd->Invalidate();

    HTuple  hv_WindowHandle;
    dev_open_window_fit_image(m_object, 0, 0, -1, -1, &hv_WindowHandle);
    if (HDevWindowStack::IsOpen())
        ClearWindow(HDevWindowStack::GetActive());
    if (HDevWindowStack::IsOpen())
        DispObj(m_object, HDevWindowStack::GetActive());

    // 释放DC
    ::ReleaseDC(m_pWnd->m_hWnd, m_hDC);

}

void CBmp::TraverseDir(CString& dir, vector<CString>& vec)
{
    CFileFind ff;
    if (dir.Right(1) != "/")
        dir += "/";
    dir += "*.*";

    BOOL ret = ff.FindFile(dir);
    while (ret)
    {
        ret = ff.FindNextFile();
        if (ff.IsDirectory() && !ff.IsDots())
        {
            CString path = ff.GetFilePath();
            TraverseDir(path, vec);
        }
        else if (!ff.IsDirectory() && !ff.IsDots())
        {
            CString name = ff.GetFileName();
            CString path = ff.GetFilePath();
            vec.push_back(path);
        }
    }
    ff.Close();
}

bool CBmp::HBitmapToMat(HBITMAP& _hBmp, Mat& _mat)
{
    BITMAP bmp;    
    GetObject(_hBmp,sizeof(BITMAP),&bmp);    
    int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8 ;   
    int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;    
    Mat v_mat;
    v_mat.create(cvSize(bmp.bmWidth,bmp.bmHeight), CV_MAKETYPE(CV_8U,nChannels));
    GetBitmapBits(_hBmp,bmp.bmHeight*bmp.bmWidth*nChannels,v_mat.data);  
    _mat=v_mat;
    return TRUE;   
}

void CBmp::MatToCImage(Mat& mat, CImage& cimage)
{
     if (0 == mat.total())  
    {  
        return;  
    }  


    int nChannels = mat.channels();  
    if ((1 != nChannels) && (3 != nChannels))  
    {  
        return;  
    }  
    int nWidth    = mat.cols;  
    int nHeight   = mat.rows;  


    //重建cimage  
    cimage.Destroy();  
    cimage.Create(nWidth, nHeight, 8 * nChannels);  


    //拷贝数据  


    uchar* pucRow;                                  //指向数据区的行指针  
    uchar* pucImage = (uchar*)cimage.GetBits();     //指向数据区的指针  
    int nStep = cimage.GetPitch();                  //每行的字节数,注意这个返回值有正有负  


    if (1 == nChannels)                             //对于单通道的图像需要初始化调色板  
    {  
        RGBQUAD* rgbquadColorTable;  
        int nMaxColors = 256;  
        rgbquadColorTable = new RGBQUAD[nMaxColors];  
        cimage.GetColorTable(0, nMaxColors, rgbquadColorTable);  
        for (int nColor = 0; nColor < nMaxColors; nColor++)  
        {  
            rgbquadColorTable[nColor].rgbBlue = (uchar)nColor;  
            rgbquadColorTable[nColor].rgbGreen = (uchar)nColor;  
            rgbquadColorTable[nColor].rgbRed = (uchar)nColor;  
        }  
        cimage.SetColorTable(0, nMaxColors, rgbquadColorTable);  
        delete []rgbquadColorTable;  
    }  


    for (int nRow = 0; nRow < nHeight; nRow++)  
    {  
        pucRow = (mat.ptr<uchar>(nRow));  
        for (int nCol = 0; nCol < nWidth; nCol++)  
        {  
            if (1 == nChannels)  
            {  
                *(pucImage + nRow * nStep + nCol) = pucRow[nCol];  
            }  
            else if (3 == nChannels)  
            {  
                for (int nCha = 0 ; nCha < 3; nCha++)  
                {  
                    *(pucImage + nRow * nStep + nCol * 3 + nCha) = pucRow[nCol * 3 + nCha];  
                }             
            }  
        }     
    }  
}

void CBmp::CImageToMat(CImage& cimage, Mat& mat)  
{  
    if (true == cimage.IsNull())  
    {  
        return;  
    }  


    int nChannels = cimage.GetBPP() / 8;  
    if ((1 != nChannels) && (3 != nChannels))  
    {  
        return;  
    }  
    int nWidth    = cimage.GetWidth();  
    int nHeight   = cimage.GetHeight();  


    //重建mat  
    if (1 == nChannels)  
    {  
        mat.create(nHeight, nWidth, CV_8UC3);  
    }  
    else if(3 == nChannels)  
    {  
        mat.create(nHeight, nWidth, CV_8UC3);  
    }


    //拷贝数据  


    uchar* pucRow;                                  //指向数据区的行指针  
    uchar* pucImage = (uchar*)cimage.GetBits();     //指向数据区的指针  
    int nStep = cimage.GetPitch();                  //每行的字节数,注意这个返回值有正有负  


    for (int nRow = 0; nRow < nHeight; nRow++)  
    {  
        pucRow = (mat.ptr<uchar>(nRow));  
        for (int nCol = 0; nCol < nWidth; nCol++)  
        {  
            if (1 == nChannels)  
            {                   
                for (int nCha = 0 ; nCha < 3; nCha++)  
                {  
                    pucRow[nCol * 3 + nCha] = *(pucImage + nRow * nStep + nCol);
                }
            }  
            else if (3 == nChannels)  
            {  
                for (int nCha = 0 ; nCha < 3; nCha++)  
                {  
                    pucRow[nCol * 3 + nCha] = *(pucImage + nRow * nStep + nCol * 3 + nCha);  
                }             
            }  
        }     
    }  
}  

void CBmp::dev_open_window_fit_image (HObject ho_Image, HTuple hv_Row, HTuple hv_Column, 
    HTuple hv_WidthLimit, HTuple hv_HeightLimit, HTuple *hv_WindowHandle)
{

  // Local control variables 
  HTuple  hv_MinWidth, hv_MaxWidth, hv_MinHeight;
  HTuple  hv_MaxHeight, hv_ResizeFactor, hv_ImageWidth, hv_ImageHeight;
  HTuple  hv_TempWidth, hv_TempHeight, hv_WindowWidth, hv_WindowHeight;

  //This procedure opens a new graphics window and adjusts the size
  //such that it fits into the limits specified by WidthLimit
  //and HeightLimit, but also maintains the correct image aspect ratio.
  //
  //If it is impossible to match the minimum and maximum extent requirements
  //at the same time (f.e. if the image is very long but narrow),
  //the maximum value gets a higher priority,
  //
  //Parse input tuple WidthLimit
  if (0 != (HTuple((hv_WidthLimit.TupleLength())==0).TupleOr(hv_WidthLimit<0)))
  {
    hv_MinWidth = 500;
    hv_MaxWidth = 800;
  }
  else if (0 != ((hv_WidthLimit.TupleLength())==1))
  {
    hv_MinWidth = 0;
    hv_MaxWidth = hv_WidthLimit;
  }
  else
  {
    hv_MinWidth = ((const HTuple&)hv_WidthLimit)[0];
    hv_MaxWidth = ((const HTuple&)hv_WidthLimit)[1];
  }
  //Parse input tuple HeightLimit
  if (0 != (HTuple((hv_HeightLimit.TupleLength())==0).TupleOr(hv_HeightLimit<0)))
  {
    hv_MinHeight = 400;
    hv_MaxHeight = 600;
  }
  else if (0 != ((hv_HeightLimit.TupleLength())==1))
  {
    hv_MinHeight = 0;
    hv_MaxHeight = hv_HeightLimit;
  }
  else
  {
    hv_MinHeight = ((const HTuple&)hv_HeightLimit)[0];
    hv_MaxHeight = ((const HTuple&)hv_HeightLimit)[1];
  }
  //
  //Test, if window size has to be changed.
  hv_ResizeFactor = 1;
  GetImageSize(ho_Image, &hv_ImageWidth, &hv_ImageHeight);
  //First, expand window to the minimum extents (if necessary).
  if (0 != (HTuple(hv_MinWidth>hv_ImageWidth).TupleOr(hv_MinHeight>hv_ImageHeight)))
  {
    hv_ResizeFactor = (((hv_MinWidth.TupleReal())/hv_ImageWidth).TupleConcat((hv_MinHeight.TupleReal())/hv_ImageHeight)).TupleMax();
  }
  hv_TempWidth = hv_ImageWidth*hv_ResizeFactor;
  hv_TempHeight = hv_ImageHeight*hv_ResizeFactor;
  //Then, shrink window to maximum extents (if necessary).
  if (0 != (HTuple(hv_MaxWidth<hv_TempWidth).TupleOr(hv_MaxHeight<hv_TempHeight)))
  {
    hv_ResizeFactor = hv_ResizeFactor*((((hv_MaxWidth.TupleReal())/hv_TempWidth).TupleConcat((hv_MaxHeight.TupleReal())/hv_TempHeight)).TupleMin());
  }
  hv_WindowWidth = hv_ImageWidth*hv_ResizeFactor;
  hv_WindowHeight = hv_ImageHeight*hv_ResizeFactor;
  //Resize window
  SetWindowAttr("background_color","black");
  OpenWindow(hv_Row,hv_Column,hv_WindowWidth,hv_WindowHeight,0,"","",&(*hv_WindowHandle));
  HDevWindowStack::Push((*hv_WindowHandle));
  if (HDevWindowStack::IsOpen())
    SetPart(HDevWindowStack::GetActive(),0, 0, hv_ImageHeight-1, hv_ImageWidth-1);
  return;
}

4.使用方法

    CString* paths = new CString[1];
    paths[0] =  "C:/Users/lin/Desktop/picture/";
    //获取bmp对象
    bmp = CBmp::Instantialize(paths, 1);

    //获取图片传入路径下标码
    bmp->GetPic(0);
    //获取图片数据CBitmap
    bmp->m_bitmap;
    //获取图片数据CImage
    bmp->m_image;
    //获取图片数据HObject
    bmp->m_object;
    //获取图片数据Mat
    bmp->m_mat;


    //显示图片
    bmp->ShowPic(GetDlgItem(IDC_STATIC_SHOW_WND));
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值