GDI vs GDI+ 通杀常见图片

    技术2024-07-08  72

    通常位图(Bitmap)能够满足大多数体积小的情况了,但对于大的位图,

    如果是要放到资源,实不敢恭维啊,程序体积一下子大了N多,看着也不爽

    同样的图片,如果是PNG啊JPEG啊等其它格式,体积明显小了不是一般的多

    那么为何不用它们呢?

    微软提供了GDI+这玩意,貌似可以轻松地完成常用的格式图片,

    不过它不提供类似LoadBitmap, LoadImage之类从资源读取的直接函数

    虽然那Bitmap有成员函数FromResource(构造函数也可以)

    但实际自己用用就知道了,不是通杀的

    不过还好,微软提供了从IStream创建这一方法,

    那么我们只要把资源(或者图片文件)的数据读到这IStream就完事了

     

    下面的函数自己实现的,可以直接从资源里加载GDI+支持的图片格式

    先看代码

     

    //hInst为持有图片资源的实例句柄 //lpszResName为资源名 //lpszResType为资源类型 HBITMAP LoadPicture (HINSTANCE hInst , LPCTSTR lpszResName , LPCTSTR lpszResType ) {     if (! lpszResName || ! lpszResType ){         return NULL ;     }     //先判断是不是位图,是直接用LoadBitmap API省事     if ((WORD )lpszResType == (WORD )RT_BITMAP ){         return LoadBitmap (hInst , lpszResName );     }     //其它格式的通过查找资源方式     HRSRC hResInfo = FindResource (hInst , lpszResName , lpszResType );     if (! hResInfo ){         return NULL ;     }     HGLOBAL hResData = LoadResource (hInst , hResInfo );     if (! hResData ){         return NULL ;     }     LPVOID pSrc = LockResource (hResData );     if (! pSrc ){         return NULL ;     }     DWORD dwSize = SizeofResource (hInst , hResInfo );     if (! dwSize ){         return NULL ;     }     HGLOBAL hGlobal = GlobalAlloc (GMEM_MOVEABLE , dwSize );     if (! hGlobal ){         return NULL ;     }     LPVOID pData = GlobalLock (hGlobal );     if (! pData ){         return NULL ;     }     memcpy (pData , pSrc , dwSize );     GlobalUnlock (hGlobal );     IStream * pStream = NULL ;     //一切搞定,创建这关键的IStream了     if (FAILED (CreateStreamOnHGlobal (hGlobal , TRUE , & pStream )))         return NULL ;     if (pStream == NULL )         return NULL ;     Gdiplus :: Bitmap * pBitmap = new Gdiplus :: Bitmap (pStream );     pStream -> Release ();     HBITMAP hBitmap = NULL ;     //获取HBITMAP     pBitmap -> GetHBITMAP (NULL , & hBitmap );     delete pBitmap ;     return hBitmap ; }

    OK,就这么点

    函数名长得跟LoadBitmap像吧,只不过多了一个图片类型参数

    使用方法自然不用说了,既然返回的是HBITMAP,就跟平常时BitBlt什么的就OK了

    或许你会问,为啥不直接用GDI+画?

    这个……GDI+画图的效率不怎么地行啊,即使用上了传说中的DrawCachedBitmap等提速方法,

    也还是没有传说中的BitBlt牛X

     

     

     至于为啥没用到FreeResoure之类的API,微软这么说的

    For 32-bit Windows applications, it is not necessary to free the resources loaded using function LoadResource

    其它的看MSDN了呗

     

    至于怎么调用应该不用说了吧?不过还是啰嗦一下吧

     

    比如资源里有这么一个PNG

     

    IDB_PNG         PNG                     "working.png"

     

    那么只要

     

    HBITMAP hBitmap = LoadPicture(hInst, MAKEINTRESOURCE(IDB_PNG), TEXT("PNG"));

     

    就这么简单!!!

     

    如果想在纯C下用,那把它放到DLL里去吧,额D神~

    最新回复(0)