从资源中加载jpg, png到GDI+ Image

从资源中加载jpg和png文件, 貌似不应该是个大问题, 一google结果一大堆, 却有两个陷阱,trap啊

1, 是Bitmap(RT_BITMAP)类型的图片无法加载, RT_BITMAP是预定义类型, 资源里面没有bmp文件的头,  SizeofResource 的返回值要比图片文件 少几个字节,因为少了这几个字节, 所以GDI+会返回invalid parameter错误。

2, 从IStream里面创建出来的Image对象似乎会引用到堆里面的内存, 如果hBuffer被释放了, 创建的Image的内容就会被破坏,有时只能画出一小部分图片, 有时整个图片就是空白, 视当时的内存状况而定。调用Image的Clone也没用。

CYourClass::~CYourClass()
{
    for(IMG_VECTOR::iterator it = m_arImage.begin(); it != m_arImage.end(); it++)
        delete *it;
    for(HGLB_VECTOR::iterator it = m_arGlobal.begin(); it != m_arGlobal.end(); it++)
    {
        ::GlobalUnlock(*it);
        ::GlobalFree(*it);
    }
}

void CYourClass::AddImage(HMODULE hInst, UINT nResourceID, LPCTSTR lpType)
{
    if(lpType == RT_BITMAP)
    {
        //GDI+ can not load RT_BITMAP resouce, 
        //because they are predefined resource, 
        //they don't contains the image file header.
        assert(FALSE);
        return;
    }

    HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), lpType);
    if (!hResource)
        return;

    DWORD imageSize = ::SizeofResource(hInst, hResource);
    if (!imageSize)
        return;

    const void* pResourceData = ::LockResource(::LoadResource(hInst, hResource));
    if (!pResourceData)
        return;

    HGLOBAL hBuffer = ::GlobalAlloc(GMEM_FIXED, imageSize);
    if (NULL == hBuffer)
        return;

    void* pBuffer = ::GlobalLock(hBuffer);
    if (pBuffer)
    {
        CopyMemory(pBuffer, pResourceData, imageSize);
        IStream* pStream = NULL;
        if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK)
        {
            Gdiplus::Image * pImage = Gdiplus::Image::FromStream(pStream);
            pStream->Release();
            if (pImage)
            { 
                if (pImage->GetLastStatus() == Gdiplus::Ok &&
                    pImage->GetWidth() > 0)
                {
                    m_arImage.push_back(pImage);
                    //it seems the image will take usage of the global memory.
                    //so the global memory should be kept until the image destroy.
                    m_arGlobal.push_back(hBuffer);
                    return;
                }

                delete pImage;
            }
        }
        ::GlobalUnlock(hBuffer);
    }
    ::GlobalFree(hBuffer);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值