首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将PNG从资源加载到CImage中

如何将PNG从资源加载到CImage中
EN

Stack Overflow用户
提问于 2017-08-01 15:07:36
回答 2查看 2.7K关注 0票数 4

根据LoadFromResource的这个文档,它声明:

BITMAP资源加载图像

所以,我的代码中有这样的内容:

代码语言:javascript
复制
rImage.LoadFromResource(AfxFindResourceHandle(), IDB_PNG1);

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

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

因此,目前我正在使用外部PNG文件。效果很好。但是是否有将PNG从资源加载到CImage的任何方式?

更新

提供给我的意见很有帮助。

它把我引向这里。所以,如果我有这个方法:

代码语言:javascript
复制
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;
}

就这样叫它:

代码语言:javascript
复制
rImage.Load(CreateStreamOnResource(MAKEINTRESOURCE(IDB_PNG1), _T("PNG")));

效果很好..。谢谢你们。

更新:

根据所提供的评论。现在好多了?我看不出泄密:

代码语言:javascript
复制
IStream *pStream = CreateStreamOnResource(MAKEINTRESOURCE(uPNGResourceID), _T("PNG"));
if (pStream != nullptr)
{
    rImage.Load(pStream);
    rImage.SetHasAlphaChannel(true);
    pStream->Release();
}

附带注意:如果这些是我自己的嵌入式资源,并且我知道SetHasAlphaChannel是透明的32位资源,那么我真的需要调用吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-01 16:01:23

  1. AfxFindResource
  2. LoadResource
  3. GlobalAlloc
  4. CopyMemory
  5. CreateStreamOnHGlobal
  6. CImage::Load(IStream*...)

或者编写自己的IStream实现,从LoadResource获取指针和大小。另外,CSharedFile也是一种选择。

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

票数 3
EN

Stack Overflow用户

发布于 2021-05-11 09:23:50

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

代码语言:javascript
复制
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;
}

然后按以下方式使用该函数:

代码语言:javascript
复制
pImage = new CImage;
IStream *pStream = CreateStreamOnResource(MAKEINTRESOURCE(IDB_MYIMAGE), _T("PNG"));
if (pStream != nullptr)
{
    pImage->Load(pStream);
    pImage->SetHasAlphaChannel(true);
    pStream->Release();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45441475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档