【问题标题】:How to load a PNG from RESOURCES into a CImage如何将 RESOURCES 中的 PNG 加载到 CImage 中
【发布时间】:2018-01-08 12:52:10
【问题描述】:

根据LoadFromResource 的文档,它指出:

BITMAP 资源加载图像

所以,我的代码中有这个:

rImage.LoadFromResource(AfxFindResourceHandle(), IDB_PNG1);

不起作用。然后我意识到我使用的是 PNG 文件而不是 BMP 文件。我想这就是找不到资源的原因。

我也尝试过使用AfxGetInstanceHandle()。但这也行不通。

因此,目前我正在使用外部 PNG 文件。它工作正常。但是是否有任何方法可以将资源中的 PNG 加载到 CImage 中?

更新

提供给我的评论很有帮助。

它引导我here。所以,如果我有这个方法:

IStream* CreateStreamOnResource(LPCTSTR lpName, LPCTSTR lpType)
{
    IStream * ipStream = NULL;

    HRSRC hrsrc = FindResource(NULL, lpName, lpType);
    if (hrsrc == NULL)
        goto Return;

    DWORD dwResourceSize = SizeofResource(NULL, hrsrc);
    HGLOBAL hglbImage = LoadResource(NULL, hrsrc);
    if (hglbImage == NULL)
        goto Return;

    LPVOID pvSourceResourceData = LockResource(hglbImage);
    if (pvSourceResourceData == NULL)
        goto Return;

    HGLOBAL hgblResourceData = GlobalAlloc(GMEM_MOVEABLE, dwResourceSize);
    if (hgblResourceData == NULL)
        goto Return;

    LPVOID pvResourceData = GlobalLock(hgblResourceData);

    if (pvResourceData == NULL)
        goto FreeData;

    CopyMemory(pvResourceData, pvSourceResourceData, dwResourceSize);

    GlobalUnlock(hgblResourceData);

    if (SUCCEEDED(CreateStreamOnHGlobal(hgblResourceData, TRUE, &ipStream)))
        goto Return;

FreeData:
    GlobalFree(hgblResourceData);

Return:
    return ipStream;
}

然后这样称呼它:

rImage.Load(CreateStreamOnResource(MAKEINTRESOURCE(IDB_PNG1), _T("PNG")));

工作正常...谢谢大家。

更新:

基于提供的评论。现在好点了吗?我没有看到任何泄漏:

IStream *pStream = CreateStreamOnResource(MAKEINTRESOURCE(uPNGResourceID), _T("PNG"));
if (pStream != nullptr)
{
    rImage.Load(pStream);
    rImage.SetHasAlphaChannel(true);
    pStream->Release();
}

旁注:如果这些是我自己的嵌入式资源并且我知道是透明的 32 位资源,我真的需要致电 SetHasAlphaChannel 吗?

【问题讨论】:

  • 没有。你有内存泄漏。您必须调用 Release 到 IStream 接口。或者您使用 CComPtr 作为返回值。
  • 正如我所说,使用 CComPtr 会更容易......我假设您只需将声明更改为 CComPtr ipStream;当然还有返回值。比 rImage.Load(CreateStreamOnResource(MAKEINTRESOURCE(IDB_PNG1), _T("PNG")));是有可能的。
  • 我以为我已经提到我做了更改以调用Release。但我同意你的观点。谢谢。
  • 在我的回答中添加了一个新文本:编辑:新的 MFC 还提供了一个CPngBitmap,它允许直接从内存源将 PNG 文件作为 HBITMAP 加载。

标签: visual-c++ mfc


【解决方案1】:
  1. AfxFindResource
  2. LoadResource
  3. GlobalAlloc
  4. CopyMemory
  5. CreateStreamOnHGlobal
  6. CImage::Load(IStream*...)

或者您编写自己的IStream 实现,该实现从LoadResource 获取指针和大小。 CSharedFile 也是一个选项。

编辑:新的 MFC 还提供了一个CPngBitmap,允许直接从内存源将 PNG 文件作为 HBITMAP 加载。

【讨论】:

    【解决方案2】:

    您可以从硬编码路径或流中加载图像。要从 Stream 加载它,请使用以下代码。首先,添加一个从资源创建流的函数。

    IStream* ZDlg::CreateStreamOnResource(LPCTSTR lpName, LPCTSTR lpType)
    {
        IStream * ipStream = NULL;
    
        HRSRC hrsrc = FindResource(NULL, lpName, lpType);
        if (hrsrc == NULL)
            goto Return;
    
        DWORD dwResourceSize = SizeofResource(NULL, hrsrc);
        HGLOBAL hglbImage = LoadResource(NULL, hrsrc);
        if (hglbImage == NULL)
            goto Return;
    
        LPVOID pvSourceResourceData = LockResource(hglbImage);
        if (pvSourceResourceData == NULL)
            goto Return;
    
        HGLOBAL hgblResourceData = GlobalAlloc(GMEM_MOVEABLE, dwResourceSize);
        if (hgblResourceData == NULL)
            goto Return;
    
        LPVOID pvResourceData = GlobalLock(hgblResourceData);
    
        if (pvResourceData == NULL)
            goto FreeData;
    
        CopyMemory(pvResourceData, pvSourceResourceData, dwResourceSize);
    
        GlobalUnlock(hgblResourceData);
    
        if (SUCCEEDED(CreateStreamOnHGlobal(hgblResourceData, TRUE, &ipStream)))
            goto Return;
    
    FreeData:
        GlobalFree(hgblResourceData);
    
    Return:
        return ipStream;
    }
    

    然后使用如下函数:

    pImage = new CImage;
    IStream *pStream = CreateStreamOnResource(MAKEINTRESOURCE(IDB_MYIMAGE), _T("PNG"));
    if (pStream != nullptr)
    {
        pImage->Load(pStream);
        pImage->SetHasAlphaChannel(true);
        pStream->Release();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-08
      • 2012-11-13
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多