How to load a png resource into picture control on

2019-04-19 22:44发布

I tried the following code on OnInitDialog() but nothing was shown.

m_staticLogo.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_LOGO)));

where m_staticLogo is the static picture control and IDB_LOGO is the resource ID of the png file.

4条回答
该账号已被封号
2楼-- · 2019-04-19 23:09

For those, who need quick solution, here is a way to load png file from resources using GDI+ (original answer for standard GDI from here - http://www.codeproject.com/Questions/377803/How-to-load-PNG-images-in-mfc):

bool GdiPlusUtils::LoadBitmapFromPNG(UINT uResourceID, 
    Bitmap** ppBitmapOut, HINSTANCE hInstance /*= NULL*/)
{
    bool bRet = false;

    if (!hInstance)
        hInstance = AfxGetInstanceHandle();

    HRSRC hResourceHandle = ::FindResource(
        hInstance, MAKEINTRESOURCE(uResourceID), L"PNG");
    if (0 == hResourceHandle)
    {
        return bRet;
    }

    DWORD nImageSize = ::SizeofResource(hInstance, hResourceHandle);
    if (0 == nImageSize)
    {
        return bRet;
    }

    HGLOBAL hResourceInstance = ::LoadResource(hInstance, hResourceHandle);
    if (0 == hResourceInstance)
    {
        return bRet;
    }

    const void* pResourceData = ::LockResource(hResourceInstance);
    if (0 == pResourceData)
    {
        FreeResource(hResourceInstance);
        return bRet;
    }

    HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, nImageSize);
    if (0 == hBuffer)
    {
        FreeResource(hResourceInstance);
        return bRet;
    }

    void* pBuffer = ::GlobalLock(hBuffer);
    if (0 != pBuffer)
    {
        CopyMemory(pBuffer, pResourceData, nImageSize);
        IStream* pStream = 0;
        if (S_OK == ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream))
        {
            *ppBitmapOut = new Bitmap(pStream);
            pStream->Release();
            bRet = true;
        }
        ::GlobalUnlock(hBuffer);
    }
    ::GlobalFree(hBuffer);

    UnlockResource(hResourceInstance);
    FreeResource(hResourceInstance);

    return bRet;
}

You can add png file as resource using Add Resource command and in the panel choose Import.

查看更多
做自己的国王
3楼-- · 2019-04-19 23:13

Bitmap and icon it supports. Not sure about png. Alternately, May be you can try the following.

  1. open png in MS Paint or some other viewer.
  2. Then copy the image portion from that.
  3. Create a resource in MFC resource.
  4. Paste the copied image to newly created resource.
  5. Use new resource id in LoadBitmap.
查看更多
\"骚年 ilove
4楼-- · 2019-04-19 23:21

If you are converting .png image file to .bmp format, you can end up with image clarity. So, catch WM_PAINT message in dialog box class and use

Graphics::DrawImage method

To obtain this method link your project with gdiplus.lib library.

查看更多
孤傲高冷的网名
5楼-- · 2019-04-19 23:22

As you’ve discovered, ::LoadBitmap (and the newer ::LoadImage) only deal with .bmps. By far the easiest solution is to convert your image to a .bmp.

If the image has transparency, it can be converted into a 32-bit ARGB bitmap (here is a tool called AlphaConv that can convert it). Then load the image using the CImage class LoadFromResource method. Pass the CImage to m_staticLogo.SetBitmap().

But if you really need it to be a .png, it can be done.

Method 1 (the easier way): Load the .png from a file using CImage::Load. Pass the CImage to m_staticLogo.SetBitmap().

Method 2 (the harder way): Load the .png from a resource by loading the resource into a COM IStream and using CImage::Load. (NOTE: CImage::LoadFromResource looks tempting but will not work with a .png graphic). To get the resource into a COM IStream, see this Codeproject article. Note the article works with Gdiplus::Bitmap but the key part is how to create the IStream, which you should be able to adapt for CImage. Finally, pass the CImage to m_staticLogo.SetBitmap().

Edit: Updated to use CImage, which is easier than Gdiplus::Bitmap.

查看更多
登录 后发表回答