将 PNG 资源加载到 CBitmap 中

发布于 2024-09-05 02:56:52 字数 234 浏览 2 评论 0原文

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

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

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

How do I load a png resource into a CBitMap? When I try this it doesn't seem to work:

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

It gives me an error resource type not found. Is there any other way to load a PNG resource?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦里°也失望 2024-09-12 02:56:52

如果您使用的是 VS2008 或更新版本(MFC 功能包),则可以使用从 CBitmap 派生并包含在 中的 CPngImage >。 CPngImage 是一个

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

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

#define AFX_PNG_RESOURCE_TYPE _T("PNG")

用法示例

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

If you are using VS2008 or newer (MFC Feature Pack) you can use CPngImage which derives from CBitmap and is contained in <afxtoolbarimages.h>. CPngImage is an internal class:

The following classes are used internally in MFC. For completeness, this section describes these internal classes, but they are not intended to be used directly in your code.

If you want to use CPngImage you need to use the resource type "PNG":

#define AFX_PNG_RESOURCE_TYPE  _T("PNG")

Example usage

CPngImage image;
image.Load(IDB_PNG1, nullptr);
bitmap.Attach(image.Detach());
幸福丶如此 2024-09-12 02:56:52

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

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

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

LoadFromResource uses LoadImage internally, it doesn't support PNG last time I tried, despite what the documentation says. You can link with CxImage (look on CodeProject) but it's a lot of work for little real benefit.

What I did in the end was forget about PNG, use AlphaConv to convert PNG's into 32-bit Windows bitmaps and use CImage with those. Additional advantage is that you can use them with CBitmapButton etc. in MFC without any transformations.

Another way to hack around it is to extract the resource contents to a temporary file, then use CImage::Load to read it from there. If I'd catch you doing that in one of my code bases I'd punch you in the face though ;)

此刻的回忆 2024-09-12 02:56:52

如果您确实不需要 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;
}

If you do not really need a CBitmap, but only an handle this may useful for you.

Or if you can get a CBitmap from the HBITMAP this function returns it is also good.

I use this on a commercial application and it works.

// 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;
}
执手闯天涯 2024-09-12 02:56:52

使用像 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 来绘制图形在我的程序中,它极大地简化了事情。

Use a library like CxImage (http://www.xdp.it/cximage.htm) to do all the heavy lifting for you. The code becomes as simple as :-

CxImage image;
if (image.LoadResource(<resource_instance_handle>, <resource_id>, CXIMAGETYPE_PNG))
{
    HBITMAP hbmp = image.CreateHBITMAP();
    ... do something with hbmp ...
}

(note that I'm writing this code from memory -- you may need to tweak it slightly to get it to work!)

I use CxImage a lot for the graphics in my programs and it simplifies things tremendously.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文