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