VC Load picture from a file

With MFC do GDI develop friends certainly familiar CBitmap class that encapsulates the HBITMAP objects, simplifying on HBITMAP the API operations, such as LoadBitmap method can be loaded directly specified in the resource ID of the picture, but in many cases we need to be loaded from a file picture, CBitmap class did not provide such a method.

Below I summarize several ways to load a picture from a file that I know:

 

1. Use API functions LoadImage , designated LR_LOADFROMFILE flag. Such as:

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

This way is very simple, but according to my experiments, this method seems to only load pictures bmp format to jpg / png and other formats are not loaded, really depressed.

 

2. Using COM, I CodeGuru some time ago in Amoy Taobao to this method, I sorted out the code as follows:

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加载的方法实用多了,也方便多了。

 

Other: Understanding HBITMAP master general structure of picture files can read, analyze the data stream. As for people like me passing by, so do not engage in the complex. Yes, there is a relatively large open source projects CxImage, eDonkey source code to use it.

Reproduced in: https: //my.oschina.net/dake/blog/196856

Guess you like

Origin blog.csdn.net/weixin_34391445/article/details/91586259