如何将 png 资源加载到
CBitMap
中?当我尝试这个时,它似乎不起作用:
CImage image;
image.LoadFromResource(AfxGetInstanceHandle(), IDB_PNG1);
bitmap.Attach(image.Detach());
它给我一个错误资源类型未找到。还有其他方法可以加载PNG资源吗?
如果您使用的是 VS2008 或更新版本(MFC 功能包),您可以使用
CPngImage
,它派生自 CBitmap
并包含在 <afxtoolbarimages.h>
中。 CPngImage
是一个内部类:
以下类在 MFC 内部使用。为了完整起见,本节描述了这些内部类,但它们并不打算直接在您的代码中使用。
如果你想使用
CPngImage
,你需要使用资源类型"PNG"
:
#define AFX_PNG_RESOURCE_TYPE _T("PNG")
CPngImage image;
image.Load(IDB_PNG1, nullptr);
bitmap.Attach(image.Detach());
LoadFromResource
在内部使用 LoadImage
,我上次尝试时它不支持 PNG,不管文档怎么说。您可以与 CxImage
链接(查看 CodeProject),但这需要大量工作,但几乎没有真正的好处。
我最终所做的就是忘记 PNG,使用
AlphaConv
将 PNG 转换为 32 位 Windows 位图,然后使用 CImage
来处理这些位图。另一个优点是您可以在 MFC 中将它们与 CBitmapButton
等一起使用,而无需任何转换。
另一种破解方法是将资源内容提取到临时文件中,然后使用
CImage::Load
从那里读取它。如果我发现你在我的一个代码库中这样做,我会打你的脸;)
如果您并不真正需要
CBitmap
,而只需要一个手柄,这可能对您有用。
或者,如果您可以从
CBitmap
中获得 HBITMAP
,此函数返回也很好。
我在商业应用程序上使用它并且它有效。
// Based on afxbutton.cpp's static function ButtonLoadBitmap
HBITMAP __stdcall ButtonLoadBitmap(UINT uiBmpResId)
{
if (uiBmpResId == 0)
{
return NULL;
}
LPCTSTR lpszResourceName = MAKEINTRESOURCE(uiBmpResId);
ENSURE(lpszResourceName != NULL);
HBITMAP hbmp = NULL;
// Try to load PNG image first:
CPngImage pngImage;
if (pngImage.Load(lpszResourceName))
{
hbmp = (HBITMAP) pngImage.Detach();
}
else
{
HINSTANCE hinstRes = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
if (hinstRes == NULL)
{
return NULL;
}
UINT uiLoadImageFlags = LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS;
hbmp = (HBITMAP) ::LoadImage(hinstRes, lpszResourceName, IMAGE_BITMAP, 0, 0, uiLoadImageFlags);
}
return hbmp;
}
使用像
CxImage
(http://www.xdp.it/cximage.htm) 这样的库来为您完成所有繁重的工作。代码变得如此简单:-
CxImage image;
if (image.LoadResource(<resource_instance_handle>, <resource_id>, CXIMAGETYPE_PNG))
{
HBITMAP hbmp = image.CreateHBITMAP();
... do something with hbmp ...
}
(请注意,我是凭记忆编写这段代码的——您可能需要稍微调整一下才能使其正常工作!)
我在程序中经常使用
CxImage
来制作图形,它极大地简化了事情。