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 »

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 125 times
the transparent PNG used to draw the second red rectangle
the transparent PNG used to draw the second red rectangle
transparent.png (224 Bytes) Viewed 2267 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 »

Here are the results in MacOS
Attachments
Resulting bitmap (OK)
Resulting bitmap (OK)
result-MacOS.png (199 Bytes) Viewed 2266 times
Screenshot in MacOS (OK)
Screenshot in MacOS (OK)
screenshot-MacOS.png (10.29 KiB) Viewed 2266 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 »

Here are the results in Windows
Attachments
Resulting bitmap (NOK)
Resulting bitmap (NOK)
result-Win.png (197 Bytes) Viewed 2265 times
Screenshot in Windows (NOK)
Screenshot in Windows (NOK)
screenshot-Win.png (586 Bytes) Viewed 2265 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 »

under wxGTK, it doesn't work too...
Attachments
no transparency
no transparency
result.png (239 Bytes) Viewed 2254 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 »

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 »

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