C++ 将png资源加载到CBitMap中

C++ 将png资源加载到CBitMap中,c++,mfc,C++,Mfc,如何将png资源加载到CBitMap?当我尝试这个时,它似乎不起作用: CImage image; image.LoadFromResource(AfxGetInstanceHandle(), IDB_PNG1); bitmap.Attach(image.Detach()); 它给我一个找不到资源类型的错误。是否有其他方法加载PNG资源?LoadFromResource在内部使用LoadImage,尽管文档中有说明,但上次我尝试加载时它不支持PNG。您可以链接到CxImage(look on

如何将png资源加载到
CBitMap
?当我尝试这个时,它似乎不起作用:

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

它给我一个找不到资源类型的错误。是否有其他方法加载PNG资源?

LoadFromResource在内部使用LoadImage,尽管文档中有说明,但上次我尝试加载时它不支持PNG。您可以链接到CxImage(look on codeproject),但这需要做大量的工作,但实际效益很小

我最后做的是忘记PNG,使用AlphaConv将PNG转换为32位Windows位图,并使用CImage处理这些位图。另外一个优点是,您可以在MFC中将它们与CBitmapButton等一起使用,而无需进行任何转换


另一种破解方法是将资源内容提取到临时文件中,然后使用CImage::Load从那里读取。如果我发现你在我的代码库中这样做,我会打你的脸;)

使用CxImage()之类的库为您完成所有繁重的工作。代码变得非常简单,如下所示:-

CxImage image;
if (image.LoadResource(<resource_instance_handle>, <resource_id>, CXIMAGETYPE_PNG))
{
    HBITMAP hbmp = image.CreateHBITMAP();
    ... do something with hbmp ...
}
CxImage;
if(image.LoadResource(,CXIMAGETYPE_PNG))
{
HBITMAP hbmp=image.CreateHBITMAP();
…用hbmp做点什么。。。
}
(请注意,我是从内存中编写此代码的——您可能需要稍微调整它才能使其正常工作!)


在我的程序中,我经常使用CxImage作为图形,它极大地简化了事情。

如果您使用的是VS2008或更高版本(MFC功能包),您可以使用
CpnImage
,它源自
CBitmap
,包含在
中:

以下类在MFC内部使用。为了完整起见,本节描述了这些内部类,但它们不打算直接在代码中使用

如果要使用
CPngImage
,则需要使用资源类型
“PNG”

示例用法
如果您真的不需要CBitmap,而只需要一个句柄,这可能对您有用

或者,如果可以从HBITMAP获取CBitMap,则此函数返回的结果也很好

我在一个商业应用程序中使用了它,它很有效

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

LoadFromResource或Attach中是否存在错误?+1对于真正打算捍卫其代码基础的开发人员来说,这是一个很好的发现!我希望它有更好的文档记录,我真的可以使用它很多年:(
CPngImage image;
image.Load(IDB_PNG1, nullptr);
bitmap.Attach(image.Detach());
// 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;
}