将png资源加载到CBitMap中

时间:2010-06-09 12:18:55

标签: c++ mfc

如何将png资源加载到CBitMap中? 当我尝试这个时它不起作用。

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

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

4 个答案:

答案 0 :(得分:16)

如果您使用的是VS2008或更新版本(MFC功能包),则可以使用CPngImage CBitmap,该<afxtoolbarimages.h>包含在CPngImage image; image.Load(AfxGetInstanceHandle(), IDB_PNG1); bitmap.Attach(image.Detach());

{{1}}

答案 1 :(得分:5)

LoadFromResource在内部使用LoadImage,尽管文档中有说明,但我上次尝试时它不支持PNG。你可以链接到CxImage(看看codeproject),但它的工作量很大,没什么好处。

我最终做的是忘记PNG,使用AlphaConv将PNG转换为32位Windows位图并使用CImage。另外一个好处是你可以在MFC中使用CBitmapButton等而不需要任何转换。

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

答案 2 :(得分:3)

如果你真的不需要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;
}

答案 3 :(得分: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,它极大地简化了事情。