Click here to Skip to main content
15,880,972 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I want to load PNG images. because png file may have transparent background. And I want to be replacing it with different png picture on any event.How can I display png images in a desired position on the dialog?
Posted
Updated 3-May-12 0:23am
v2

Hi,

Try this code.

void CTestMFCDlg::OnBnClickedButtonLoadPng()
{
	CString pngPath=L"c:\\test.png";
    	CImage pngImage;
	CBitmap pngBmp;	
	CDC bmDC;
	CBitmap *pOldbmp;
	BITMAP  bi;
	UINT xPos=450,yPos=300;

	CClientDC dc(this);
	
    	pngImage.Load(pngPath);
	// new code
	
	pngBmp.Attach(pngImage.Detach());
	
	bmDC.CreateCompatibleDC(&dc);

	 pOldbmp= bmDC.SelectObject(&pngBmp);
	 pngBmp.GetBitmap(&bi);
	 dc.BitBlt(xPos,yPos,bi.bmWidth,bi.bmHeight,&bmDC,0,0,SRCCOPY);	 
	 bmDC.SelectObject(pOldbmp);	 
}


-Ganesh Jeevaa
 
Share this answer
 
Comments
rtischer8277 21-Jan-16 7:28am    
This code helped me understand that original MFC does not operate natively with PNG files which contain transparency Alpha data, and that they have to be Detached and Attached to make them work. Fortunately, BCGSoft's modern MFC libraries have CBCGPToolBarImages that reads PNG files simply (Load) and directly with only a couple lines of code to implement. Transparent background is automatic.
If you want to load from resource use below function.
C++
bool Utils::LoadBitmapFromPNG(UINT uResourceID, CBitmap& BitmapOut)
{
    bool bRet = false;
    
    HINSTANCE hModuleInstance = AfxGetInstanceHandle();
    HRSRC hResourceHandle = ::FindResource(hModuleInstance, MAKEINTRESOURCE(uResourceID), L"PNG");
    if (0 == hResourceHandle)
    {
        return bRet;
    }

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

    HGLOBAL hResourceInstance = ::LoadResource(hModuleInstance, 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))
        {
            CImage ImageFromResource;
            ImageFromResource.Load(pStream);
            pStream->Release();
            BitmapOut.Attach(ImageFromResource.Detach());
            bRet = true;
        }
        ::GlobalUnlock(hBuffer);
    }
    ::GlobalFree(hBuffer);

    UnlockResource(hResourceInstance);
    FreeResource(hResourceInstance);

    return bRet;
}
 
Share this answer
 
Comments
CHill60 4-Mar-14 15:59pm    
Post is nearly 2 years old and OP confirmed that solution 2 was the correct solution
Michael Haephrati 16-May-20 13:33pm    
I checked solution 2 and one of the most important parts (LoadFromResource) doesn't work, so this isn't a good solution for loading an image from a resource.
CHill60 18-May-20 3:59am    
Ah … but did it work back in 2012 :-D
Michael Haephrati 18-May-20 5:44am    
Nope, it never worked and had it worked back in 2012, it would have worked today. There is a comment by the author saying it doesn't work. Coders come here to find answers and it doesn't mater if a good answer is from 2012.
CHill60 18-May-20 10:47am    
I was being facetious by asking if it worked in 2012 - Six years ago we, as a group, were less tolerant of old QA posts being resurrected years later, especially if the original questioner had expressed that they were happy with the solutions posted. Which is why I posted that comment.
If this 2014 response is a good answer to the 2012 question (which I gather from your comment, it isn't) then upvote it and downvote the OP's accepted solution
With CImage[^] class.
 
Share this answer
 
Comments
chaiein 3-May-12 6:36am    
how can i do without mouse or key event? that is using CRect
chaiein 3-May-12 6:40am    
Error 3 error C2065: 'CImage' : undeclared identifier
CPallini 3-May-12 6:44am    
From the documentation page:
"Requirements
Header: atlimage.h"
You have to include "atlimage.h"
chaiein 3-May-12 6:49am    
image.Load(_T("./res/acoustic grand piano_small.png"));
CDC* pDC = CDC::FromHandle(image.GetDC());
CBitmap bitmap;
bitmap.Attach(image.Detach());
pDC->SelectObject(bitmap);


image.ReleaseDC();

Please correct me there is some mistake and I need to give position to place the pic
CPallini 3-May-12 7:51am    
I would ask the authors:
http://msdn.microsoft.com/en-us/library/ms177536(VS.80).aspx
 
Share this answer
 
Comments
Michael Haephrati 18-May-20 12:34pm    
The article mentioned in this solution contains the following statement: "Loading an image from a resource is disabled due to problems recognizing it correctly as an image", and the question happens to be about that exact disabled feature.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900