GDI vs GDI+ 通杀常见图片

通常位图(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神~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章