VC从文件中加载图片

MFC GDI 开发的朋友肯定熟悉 CBitmap 类,该类封装了 HBITMAP 对象,简化了关于 HBITMAP API 操作,如 LoadBitmap 方法可直接加载资源中指定 ID 的图片,但是很多情况下我们需要从文件中加载图片, CBitmap 类就没有提供这样的方法了。

下面我总结几种我知道的从文 件加载图片的方法:

 

1. 使用 API 函数 LoadImage ,指定 LR_LOADFROMFILE 标志。如:

HBITMAP hBitmap = (HBITMAP ) ::LoadImage (NULL , strPath , IMAGE_BITMAP , 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE );

这种方式十分简洁,但是根据我的实验,此方法貌似只能加载 bmp格式的图片,对于jpg/png等格式都加载不了,真是郁闷。

 

2.利用COM,我前段时间在CodeGuru淘宝淘到这个方法,我把代 码整理了一下,如下所示:

HBITMAP LoadImageFromFile ( PCTSTR pszBitmapFile )

{

      IPicture * pIPic ;

      IStream * pStream   = NULL ;

      HGLOBAL hGlobal ;

      void * pVoid ;

 

      FILE *fp = NULL ;

      fopen_s ( &fp , CT2A ( pszBitmapFile ),"rb" );

 

      if ( fp == NULL )return NULL ;

 

      fseek ( fp , 0, SEEK_END );

      long lFS = ftell (fp );

      fseek ( fp , 0, SEEK_SET );

      hGlobal = GlobalAlloc ( GPTR , lFS );

      if ( hGlobal == NULL )

      {

           fclose (fp );

           return NULL ;

      }

      pVoid = (void *)hGlobal ;

      fread (  pVoid , 1,  lFS ,  fp );

      fclose ( fp );

 

      // Create an IStream so IPicture can

        if ( FAILED ( CreateStreamOnHGlobal ( hGlobal ,FALSE ,&pStream ) ) )

        {

             GlobalFree (hGlobal );

             return NULL ;

        }

 

      HRESULT hr = OleLoadPicture ( pStream , 0, TRUE , IID_IPicture , (void **)&pIPic );

      pStream ->Release ();

      GlobalFree (hGlobal );

      if ( FAILED (hr ) )

      {

           return NULL ;

      }

 

      HBITMAP hBitmap = NULL ;

      pIPic ->get_Handle ( ( unsigned int *)&hBitmap );

 

      HBITMAP hBitmapRet = (HBITMAP )CopyImage ( hBitmap , IMAGE_BITMAP , 0, 0,      LR_COPYRETURNORG );

 

      pIPic ->Release ();

      return hBitmapRet ;

}

 

实验表明:这段代码可以加载JPG/GIF/BMP,对png格式加载不 了。不能使用框架的朋友可以试试这段代码,不过要注意,由于使用了COM,记得使用之前要初始化COM。

 

3.第三种方式,也是 我经常采取的方式,就是使用ATL和MFC的共享类Cimage。这个类十分强大,从它数千行的源码中就可以看出。然弱水三千,只取一瓢。用它从文件加载 图片,只算牛刀小试。

  CImage img;

  img.Load( strPath );

  if( !img.IsNull() )

  {

    HBITMAP hBitmap = img.Detach();

  }

  我实验过的图片都能加载,而且很快。使用别的框架的朋友可以去研究一下 Cimage的源码,封装加载图片的功能,绝对比第二种使用COM加载的方法实用多了,也方便多了。

 

其他:理解 HBITMAP 结构的高手一般可以直接读取图片文件,分析数据流的。至于像我这样路过的人,不用搞那么复杂的了。对了, 还有个相对来说庞大的开源项目CxImage,电驴源码中就使用了 它。

转载于:https://my.oschina.net/dake/blog/196856

猜你喜欢

转载自blog.csdn.net/weixin_34391445/article/details/91586259