Reputation: 91
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?
Upvotes: 9
Views: 19083
Reputation: 19612
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 ;)
Upvotes: 6
Reputation: 896
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.
Upvotes: 1
Reputation: 4335
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;
}
Upvotes: 3
Reputation: 537
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")
CPngImage image;
image.Load(IDB_PNG1, nullptr);
bitmap.Attach(image.Detach());
Upvotes: 19