I need to draw PNG images with transparency. I use GDI, GDI+, and WinApi.
To load and draw images, I always used GDI+, but now I'm using more "native" GDI algorithms (StretchBlt
, etc).
The problem is that GDI can't load PNG. I searched the internet and found 2 ways:
- loading via GDI+
- using WIC.
WIC seems to be too difficult (but what did I expect?), so I choose the first one.
It's easy to load a PNG image using GDI+, just create a Bitmap
object passing the file path to the constructor, then call the getHBITMAP()
method to receive an HBITMAP
handle, and that's all.
The problem is that the HBITMAP
produced by Bitmap
loses transparency.
I searched how to fix it. There are different ways - like passing Color::Black
as first argument, etc. But it doesn't work.
So, how can I Ioad a PNG image and convert it to HBITMAP
with transparency?
I don't use DrawImage method, because it's slow, GDI is faster
I pinned the code:
I understood my mistake: I have to blit hdc_mem to hdcc firstly, and then blit the image. I've did it, but i have a new problem¬_¬
I made a class to manage uploaded images, here the code:
class Imagee
{
HDC hdc; HBITMAP bm;
Imagee(HDC hdc, HBITMAP bm, another args)
{
this->hdc=CreateCompatibleDC(hdc);
this->bm=bm;
SelectObject(this->hdc,this->bm);
}
void draw(int hdcc, int x,int y, int cx, int cy)
{
**StretchBlt(this->hdc,0,0,cx,cy,hdcc,x,y,cx,cy,SRCCOPY); //I'VE ADDED THIS
SelectObject(this->hdc,this->bm); //AND THIS **
StretchBlt(this->hdcc,x,y,cx,cy,hdc,0,0,cx,cy,SRCCOPY);
};
};
Imagee *image;
void render()
{
for(;;)
{
//some draws
//Loading a bitmap via Gdi+, calling a GetHBITMAP function, HBITMAP variable named hbm
if(image==0)
image=new Imagee(hdc_mem, hbm, x, y etc..);
image->draw(hdc_mem, x, y etc..);
StretchBlt(hdc_main,0,0,1920,1080,hdc_mem,0,0,1920,1080,SRCCOPY);
}
I have a black screen. It seems I can't call SelectObject again, yes?
Graphics
object for anHDC
and then pass theBitmap
toGraphics::DrawImage()
. See Loading and Displaying Bitmaps in the GDI+ documentation. If you have to resort to GDI, see How would I load a PNG image using Win32/GDI (no GDI+ if possible)?. – Remy LebeauGetHBITMAP(Gdiplus::Color::Transparent, &hBitmap)
for some special cases. – Barmak ShemiraniSRCCOPY
doesn't perform alpha blending. A simple block transfer (whichSRCCOPY
does) is a lot faster than alpha blending. Given the code, it's unclear, what you really need. The code (like its formatting) is severely broken. Get a copy of Petzold's Programming Windows®. – IInspectable