wxMSW: transparency bug in wxMemoryDC ? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
User avatar
alchemist
Experienced Solver
Experienced Solver
Posts: 80
Joined: Tue Sep 04, 2007 6:03 pm
Location: Lembeek - Belgium
Contact:

wxMSW: transparency bug in wxMemoryDC ?

Post by alchemist » Tue Apr 29, 2008 1:58 pm

Hello,

I want to programmatically create transparent bitmaps based on transparent bitmaps (from PNG files) and DC methods (e.g. DrawRectangle), and later draw them transparently on the window's DC.

To achieve that, I use wxMemoryDC, but it seems that the resulting bitmap is completely screwed up: it is as if the alpha channel is lost, and the whole bitmap is completely transparent, event on the opaque elements.

On my example, I draw two filled red rectangles:
- one from a transparent PNG file (transparent.png)
- one with wxDC.DrawRectangle

This operation is first done directly on the window filled with a ugly coloured gradient, then into a wxBitmap which is drawn and blitted. The bitmap is also saved as a png file "result.png".

In MacOS, the resulting file is correct (2 red rectangles on a transparent background), but not in Windows (a fully transparent bitmap with maybe 2 reds transparent rectangles).

And on the display, this is also not correct.

Is there a bug in wxMSW ?

Code: Select all

#include "wx/wx.h"

class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};

class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
private:
  void OnPaint(wxPaintEvent &event);
  void OnErase(wxEraseEvent &event);

  void drawStuff(wxDC *dc);
  
  wxBitmap file_;

  DECLARE_EVENT_TABLE()
};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    if ( !wxApp::OnInit() )
        return false;
	wxImage::AddHandler(new wxPNGHandler);

    MyFrame *frame = new MyFrame(_T("Transparency tests"));
    frame->Show(true);
    return true;
}

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_PAINT(MyFrame::OnPaint)
  EVT_ERASE_BACKGROUND(MyFrame::OnErase)
END_EVENT_TABLE()


MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
{
	file_ = wxBitmap(wxImage(L"transparent.png"));
	SetClientSize(wxSize(340, 120));
}


void MyFrame::OnErase(wxEraseEvent &event)
{
	wxDC *dc(event.GetDC());
	dc->GradientFillLinear(wxRect(GetClientRect()), *wxBLUE, *wxGREEN, wxSOUTH);
}



void MyFrame::drawStuff(wxDC *dc)
{
	// draw a red rectangle 
	dc->SetBrush(*wxRED_BRUSH);
	dc->SetPen(*wxTRANSPARENT_PEN);
	dc->DrawRectangle(10, 10, 30, 30);

	// draw the same rectangle from a file
	dc->DrawBitmap(file_, 50, 00, true);
}

void MyFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
{
	wxPaintDC dc(this);

	drawStuff(&dc);
	
	wxBitmap buf(100, 50);
	buf.UseAlpha();
	
	wxMemoryDC *memDC = new wxMemoryDC(buf);
	memDC->SetBackground(*wxTRANSPARENT_BRUSH);
	memDC->Clear();
	delete memDC;

	memDC = new wxMemoryDC(buf);
	drawStuff(memDC);
	delete memDC;
	
	buf.SaveFile(_("result.png"), wxBITMAP_TYPE_PNG);

	// DrawBitmap
	dc.DrawBitmap(buf, 120,  0, true);
	dc.DrawBitmap(buf, 120, 70, false);
	
	// blit
	memDC = new wxMemoryDC(buf);
	dc.Blit(240,  0, 100, 50, memDC, 0, 0);
	dc.Blit(240, 70, 100, 50, memDC, 0, 0, wxCOPY, true);
	delete memDC;
}
Attachments
minimal.cpp
The source code
(1.92 KiB) Downloaded 75 times
transparent.png
the transparent PNG used to draw the second red rectangle
transparent.png (224 Bytes) Viewed 1668 times
Last edited by alchemist on Tue Apr 29, 2008 2:03 pm, edited 1 time in total.
Kind Regards,
Xavier Miller.
http://xaviermiller.be

User avatar
alchemist
Experienced Solver
Experienced Solver
Posts: 80
Joined: Tue Sep 04, 2007 6:03 pm
Location: Lembeek - Belgium
Contact:

Results in Mac OS (OK)

Post by alchemist » Tue Apr 29, 2008 2:00 pm

Here are the results in MacOS
Attachments
result-MacOS.png
Resulting bitmap (OK)
result-MacOS.png (199 Bytes) Viewed 1667 times
screenshot-MacOS.png
Screenshot in MacOS (OK)
screenshot-MacOS.png (10.29 KiB) Viewed 1667 times
Kind Regards,
Xavier Miller.
http://xaviermiller.be

User avatar
alchemist
Experienced Solver
Experienced Solver
Posts: 80
Joined: Tue Sep 04, 2007 6:03 pm
Location: Lembeek - Belgium
Contact:

Results in Windows (NOK)

Post by alchemist » Tue Apr 29, 2008 2:01 pm

Here are the results in Windows
Attachments
result-Win.png
Resulting bitmap (NOK)
result-Win.png (197 Bytes) Viewed 1666 times
screenshot-Win.png
Screenshot in Windows (NOK)
screenshot-Win.png (586 Bytes) Viewed 1666 times
Kind Regards,
Xavier Miller.
http://xaviermiller.be

User avatar
alchemist
Experienced Solver
Experienced Solver
Posts: 80
Joined: Tue Sep 04, 2007 6:03 pm
Location: Lembeek - Belgium
Contact:

Post by alchemist » Tue Apr 29, 2008 6:10 pm

under wxGTK, it doesn't work too...
Attachments
result.png
no transparency
result.png (239 Bytes) Viewed 1655 times
Kind Regards,
Xavier Miller.
http://xaviermiller.be

User avatar
alchemist
Experienced Solver
Experienced Solver
Posts: 80
Joined: Tue Sep 04, 2007 6:03 pm
Location: Lembeek - Belgium
Contact:

Post by alchemist » Sun May 04, 2008 8:33 pm

No idea ?
Kind Regards,
Xavier Miller.
http://xaviermiller.be

User avatar
alchemist
Experienced Solver
Experienced Solver
Posts: 80
Joined: Tue Sep 04, 2007 6:03 pm
Location: Lembeek - Belgium
Contact:

Post by alchemist » Wed May 07, 2008 3:29 pm

Hello

I need to use wxGCDC, in order to use GDI+ in Windows.

I found that quite neird, but it works (thank you DoubleMax !)
Kind Regards,
Xavier Miller.
http://xaviermiller.be

Post Reply