将 PNG 资源加载到 CBitmap 中

问题描述 投票:0回答:4

如何将 png 资源加载到

CBitMap
中?当我尝试这个时,它似乎不起作用:

CImage image;
image.LoadFromResource(AfxGetInstanceHandle(), IDB_PNG1);
bitmap.Attach(image.Detach());

它给我一个错误资源类型未找到。还有其他方法可以加载PNG资源吗?

c++ bitmap mfc png
4个回答
19
投票

如果您使用的是 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());

6
投票

LoadFromResource
在内部使用
LoadImage
,我上次尝试时它不支持 PNG,不管文档怎么说。您可以与
CxImage
链接(查看 CodeProject),但这需要大量工作,但几乎没有真正的好处。

我最终所做的就是忘记 PNG,使用

AlphaConv
将 PNG 转换为 32 位 Windows 位图,然后使用
CImage
来处理这些位图。另一个优点是您可以在 MFC 中将它们与
CBitmapButton
等一起使用,而无需任何转换。

另一种破解方法是将资源内容提取到临时文件中,然后使用

CImage::Load
从那里读取它。如果我发现你在我的一个代码库中这样做,我会打你的脸;)


3
投票

如果您并不真正需要

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;
}

1
投票

使用像

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
来制作图形,它极大地简化了事情。

© www.soinside.com 2019 - 2024. All rights reserved.