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神~

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