CImage类学习

CImage学习笔记
 Visual C++的CBitmap类加载各种位图资源,然后处理.Visual C++的CBitmap类的功能是比较弱的,它只能显示出在资源中的图标、位图、光标以及图元文件的内容,而不能显示出绝大多数的外部图像文件(BMP、GIF、JPEG等)。如果想要在对话框或其他窗口中显示外部图像文件则只能借助于第三方提供的控件或代码。CImage是MFC和ATL共享的一个新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示,而且这些文件格式可以相互转换。例如通过简单的几句,就可以实现CImage类和CBitmap类实例的:
  HBITMAP hBitmap=image.Detach();
  CBitmap bmp;
  bmp.Attach(hBitmap);
 这样一来,和操纵CBitmap的方式雷同.CImage本身封装了DIB(设备无关位图)的功能,因而能够处理每个位图像素。它具有下列最酷特性:
  1、AlphaBlend支持像素级的颜色混合,从而实现透明和半透明的效果。
  2、PlgBlt能使一个矩形区域的位图映射到一个平行四边形区域中,而且还可能使用位屏蔽操作。
  3、TransparentBlt在目标区域中产生透明图像,SetTransparentColor用来设置某种颜色是透明色。
  4、MaskBlt在目标区域中产生源位图与屏蔽位图合成的效果。
 由于CImage在不同的Windows操作系统中其某些性能是不一样的,因此在使用时要特别注意。例如,CImage::PlgBlt和CImage::MaskBlt只能在 Windows NT 4.0 或更高版本中使用,但不能运行在Windows 95/98 应用程序中。CImage::AlphaBlend和CImage::TransparentBlt也只能在 Windows 2000/98或其更高版本中使用。即使在Windows 2000运行程序还必须将stdafx.h文件中的WINVER和_WIN32_WINNT的预定义修改成0x0500才能正常使用。

 使用CImage的一般方法是这样的过程:
 (1) 打开应用程序的stdafx.h文件添加CImage类的包含文件:#include <atlimage.h>
 (2) 定义一个CImage类对象,然后调用CImage::Load方法装载一个外部图像文件。
 (3) 调用CImage::Draw方法绘制图像。Draw方法具有如下定义:
  BOOL Draw( HDC hDestDC, int xDest, int yDest,
        int nDestWidth, int nDestHeight, int xSrc, int ySrc,
        int nSrcWidth, int nSrcHeight );
  BOOL Draw( HDC hDestDC, const RECT& rectDest, const RECT& rectSrc );
  BOOL Draw( HDC hDestDC, int xDest, int yDest );
  BOOL Draw( HDC hDestDC, const POINT& pointDest );
  BOOL Draw( HDC hDestDC, int xDest, int yDest,
        int  nDestWidth, int nDestHeight );
  BOOL Draw( HDC hDestDC, const RECT& rectDest );
 其中,hDestDC用来指定绘制的目标设备环境句柄,(xDest, yDest)和pointDest用来指定图像显示的位置,这个位置和源图像的左上角点相对应。nDestWidth和nDestHeight分别指定图像要显示的高度和宽度,xSrc、ySrc、nSrcWidth和nSrcHeight用来指定要显示的源图像的某个部分所在的位置和大小。rectDest和rectSrc分别用来指定目标设备环境上和源图像所要显示的某个部分的位置和大小。需要说明的是,Draw方法综合了StretchBlt、TransparentBlt和AlphaBlend函数的功能。默认时,Draw的功能和StretchBlt相同。但当图像含有透明色或Alpha通道时,它的功能又和TransparentBlt、AlphaBlend相同。因此,在一般情况下,我们都应该尽量调用CImage::Draw方法来绘制图像。

 一个相对完整的步骤
  //加载图片
  BOOL CPicTestDlg::LoadMyJpegFile(CString fname,LPPICTURE *lppi)
    {
        HANDLE hFile=CreateFile(fname,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
        if(hFile==INVALID_HANDLE_VALUE)
        {
            return FALSE;
        }   
        //取得文件大小
        DWORD dwFileSize=GetFileSize(hFile,NULL);
        if((DWORD)-1==dwFileSize)
        {
            CloseHandle(hFile);
            return FALSE;
        }
        //读取图像文件
        LPVOID pvData;
        //按文件大小分配内存
        HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);
        if(NULL==hGlobal)
        {
            CloseHandle(hFile);
            return FALSE;
        }
        pvData=GlobalLock(hGlobal);
        if(NULL==pvData)
        {
            GlobalUnlock(hGlobal);
            CloseHandle(hFile);
            return FALSE;
        }
        DWORD dwFileRead=0;
        BOOL bRead=ReadFile(hFile,pvData,dwFileSize,&dwFileRead,NULL);
        GlobalUnlock(hGlobal);
        CloseHandle(hFile);
        if(FALSE==bRead)
        {
            return FALSE;
        }
        LPSTREAM pstm=NULL;
       
        //从已分配内存生成IStream流     
        HRESULT hr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);
        if(!SUCCEEDED(hr))
        {
            MessageBox(_T("生成流操作失败"));
            if(pstm!=NULL)
            pstm->Release();
            return FALSE;
        }
        else if(pstm==NULL)
        {
             MessageBox(_T("生成流操作失败"));
             return FALSE;
        }
           
        if(!*lppi)(*lppi)->Release();
               
        hr=OleLoadPicture(pstm,dwFileSize,FALSE,IID_IPicture,(LPVOID*)&(*lppi));
       
        pstm->Release();
        if(!SUCCEEDED(hr))
        {
            MessageBox(_T("加载操作失败"));
            return FALSE;
        }else if(*lppi==NULL){
            MessageBox(_T("加载操作失败"));
            return FALSE;
        }
        return TRUE;
    }

    //绘制图片
   TCHAR strPath[MAX_PATH];
   memset(strPath,0,MAX_PATH);
   //得到当前路径
   GetCurrentDirectory(MAX_PATH,strPath);
   //定义图片路径
   wcscat_s(strPath,MAX_PATH,_T("\\145.bmp"));
   //加载图片到 m_lppi
   m_bHadLoad=LoadMyJpegFile(strPath,&m_lppi);
   //取得绘图设备
   CDC *pDC=GetDC();
   //定义绘图矩形区域
   CRect rc;
   //得到图片长宽
   long hmWidth=0;
   long hmHeight=0;
   m_lppi->get_Height(&hmHeight);
   m_lppi->get_Width(&hmWidth);
   //定义区域与设备关联
   GetClientRect(&rc);
   int nWidth,nHeight;
   //得到设备的长宽
   nWidth=rc.Width();
   nHeight=rc.Height();
   //绘制图片到设备区域
   HRESULT  hr=m_lppi->Render(pDC->m_hDC,nWidth,0,-nWidth,nHeight,hmWidth,hmHeight,-hmWidth,-hmHeight,&rc);
   可以在mfc的窗体中的任何地方绘制图片,重绘的时候,需要在方法OnPaint()中加以定义,另外可以在OnInitDialog()中提前加载图片到内存中.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值