【问题标题】:Load a png resource into a CBitMap将 png 资源加载到 CBitMap
【发布时间】:2011-03-01 15:30:01
【问题描述】:

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

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

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

【问题讨论】:

  • 错误是在LoadFromResource还是在Attach?

标签: c++ mfc


【解决方案1】:

如果您使用的是 VS2008 或更新版本(MFC 功能包),您可以使用源自CBitmap 并包含在<afxtoolbarimages.h> 中的CPngImageCPngImageinternal class

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

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

#define AFX_PNG_RESOURCE_TYPE  _T("PNG")

示例用法

CPngImage image;
image.Load(IDB_PNG1, nullptr);
bitmap.Attach(image.Detach());

【讨论】:

  • 好发现!我希望它有更好的记录,我真的可以使用它多年:(
【解决方案2】:

LoadFromResource 在内部使用 LoadImage,我上次尝试时它不支持 PNG,尽管文档说。您可以与 CxImage 链接(查看 codeproject),但它需要做很多工作而没有什么真正的好处。

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

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

【讨论】:

  • +1 给真正要捍卫自己的代码库的开发人员
【解决方案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;
}

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2014-05-20
      • 2011-02-15
      • 2011-01-06
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      相关资源
      最近更新 更多