draw transparent image over another image

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
manteez
Experienced Solver
Experienced Solver
Posts: 58
Joined: Fri Dec 07, 2007 7:54 am

draw transparent image over another image

Post by manteez » Wed Feb 04, 2009 4:40 am

Hello everybody,

I want to have a transparent image over another image in my application.

I've painted my frame with an image. I have a panel inside it and I paint it with my transparency image (a rectangle with opacity value 54, I created it with inkscape)

But this is what I got
Image

the result that I want is like this

Image

here is the snippet of my code

Code: Select all

....
// my panel object
Panel1 = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxSize(150,150), wxTAB_TRAVERSAL, _T("ID_PANEL1"));
Panel1->Connect(ID_PANEL1,wxEVT_PAINT,(wxObjectEventFunction)&BackgroundBitmap2Frame::OnPanel2Paint,0,this);
....
....
// I paint my frame using wxBackgroundBitmap
// I got wxBackgroundBitmap from this forum
wxBitmap pic("xp.jpg", wxBITMAP_TYPE_JPEG);
wxBackgroundBitmap *Background = new wxBackgroundBitmap(pic );
this->PushEventHandler(Background);
....
my panel OnPaint method

Code: Select all

void BackgroundBitmap2Frame::OnPanel2Paint(wxPaintEvent& event)
{
    // bgpanel3.png is my transparency image 
    wxPaintDC dc(Panel1);
    wxImage Image;
    Image.LoadFile("bgpanel3.png", wxBITMAP_TYPE_PNG);
    wxBitmap Bitmap(Image);
    dc.DrawBitmap(Bitmap, 0, 0, true);
}
what should I do to fix this problem?

Thank you

User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch » Thu Feb 05, 2009 9:56 pm

I'm not 100% sure of this, but I don't think alpha blending is supported by DC blit functions or bitmap drawing functions.

Only solutions I can think of would be to do the blitting by hand (ew -- especilly since you can't access raw pixel data in wxBitmaps, so you'd have to do wxImage conversions). Or -- do this in a wxGLCanvas and let OpenGL do the alpha blending.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Fri Feb 06, 2009 12:50 am

Maybe don't use this automatic background item; since you're using a paint handler anyway, you could probably draw everything from the paint event and have more control

Disch: If I believe what's written in the docs, it's only pens and brushes that can't be transparent on non-mac platforms.

User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Post by Disch » Fri Feb 06, 2009 2:07 am

The only mention I noticed in the reference docs is a short blurb in wxDC:
Support for Transparency / Alpha Channel

On Mac OS X when using Core Graphics (wx_MAC_USE_CORE_GRAPHICS set to 1) colors with alpha are supported, so instances wxPen or wxBrush that are built from wxColour use the color's alpha values when stroking or filling.
EDIT

Apparently it's mentioned in wxBitmap too that alpha channel is supported since 2.5.4. Whoopsie! I'll have to try that out.

Dark Alchemist
Super wx Problem Solver
Super wx Problem Solver
Posts: 347
Joined: Wed Nov 02, 2005 10:33 am

Post by Dark Alchemist » Sun Jul 26, 2009 9:51 am

I am on Windows and I can tell you transparency in wxwidgets is really bad to say the least.

I have this code

Code: Select all

    image.LoadFile(wxT("metal.jpg"), wxBITMAP_TYPE_JPEG );
    bitback = wxBitmap(image);
    WxStaticBitmap27->SetBitmap(bitback);
    image.LoadFile(wxT("1.png"), wxBITMAP_TYPE_PNG );
    bitback = wxBitmap(image);
    WxStaticBitmap28->SetBitmap(bitback);
and this is what comes out (the panel below it I made green to see what was happening):Image
So, I have a green panel with bitmap27 then bitmap28 on top of bitmap27 and look what I get.

Oh, I also tried it via dc.DrawBitmap for the background (panel and removing bitmap27 altogether) and it did the same thing so I tried it for the the static bitmap and it too was like above.

So, I have come to the conclusion that WxWidgets is incapable of doing this which negates its use for many projects I do.

leiradella
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Sep 07, 2008 9:49 pm
Location: Rio de Janeiro, Brazil

Post by leiradella » Tue Jul 28, 2009 1:54 pm

This is a wild guess, but I think maybe the background of the affected area is being erased? wxPaintDC documentation says:
Using wxPaintDC within OnPaint is important because it automatically sets the clipping area to the damaged area of the window. Attempts to draw outside this area do not appear.
If it erases the background of the affected area, this would be exactly the area your bitmap is being drawed to.

I think there is a flag somewhere to instruct wxWidgets not to erase the background but I can't find it in the docs...

You can also try Auria's suggestion of blitting both bitmaps at the paint handler, first the background and then the one with transparency.

Cheers,

Andre

User avatar
tierra
Site Admin
Site Admin
Posts: 1340
Joined: Sun Aug 29, 2004 7:14 pm
Location: Salt Lake City, Utah, USA
Contact:

Post by tierra » Tue Jul 28, 2009 4:43 pm

As Auria said, you shouldn't use wxBackgroundBitmap for this. It should just be one panel/window/frame (optimally a panel) that you tie in a paint event handler (optionally using a auto-buffered paint dc if necessary), an empty erase background handler (also if necessary, this is what leiradella was trying to get at), and draw your background, and then the image (with an alpha channel) over that.

wxDC can handle this fine, though eventually you will want to use wxGraphicsContext instead.

leiradella
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Sep 07, 2008 9:49 pm
Location: Rio de Janeiro, Brazil

Post by leiradella » Tue Jul 28, 2009 7:51 pm

Ok, I took a look at my code and what I did is creating a method to handle the EVT_ERASE_BACKGROUND event that does exactly nothing, i.e. doesn't erase anything.

Cheers,

Andre

User avatar
doublemax
Moderator
Moderator
Posts: 14082
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Wed Jul 29, 2009 8:50 am

additionally, search the forum for "msw.window.no-clip-children" which will explain why you get the observed behavior.
Use the source, Luke!

Dark Alchemist
Super wx Problem Solver
Super wx Problem Solver
Posts: 347
Joined: Wed Nov 02, 2005 10:33 am

Post by Dark Alchemist » Wed Jul 29, 2009 5:57 pm

doublemax wrote:additionally, search the forum for "msw.window.no-clip-children" which will explain why you get the observed behavior.
Well, I turned the No clip children flag on (helps rendering speed and when flipping pages you don't see that flash as much) and it still did it.

Seem like a lot of work is involved to make this behavior go away to me.

leiradella
I live to help wx-kind
I live to help wx-kind
Posts: 172
Joined: Sun Sep 07, 2008 9:49 pm
Location: Rio de Janeiro, Brazil

Post by leiradella » Wed Jul 29, 2009 6:02 pm

Maybe SDL is better suited for what you're doing?

Cheers,

Andre

User avatar
doublemax
Moderator
Moderator
Posts: 14082
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Wed Jul 29, 2009 6:08 pm

Well, I turned the No clip children flag on (helps rendering speed and when flipping pages you don't see that flash as much)
that's surprising as it should flicker much more. That's the reason why the clip-children flag is on by default.
Seem like a lot of work is involved to make this behavior go away to me.
if you want it comfortable to use and flickerfree, yes ;)
Search the forum for wxSkin, maybe it does what you need.
Use the source, Luke!

Dark Alchemist
Super wx Problem Solver
Super wx Problem Solver
Posts: 347
Joined: Wed Nov 02, 2005 10:33 am

Post by Dark Alchemist » Wed Jul 29, 2009 7:20 pm

doublemax wrote:
Well, I turned the No clip children flag on (helps rendering speed and when flipping pages you don't see that flash as much)
that's surprising as it should flicker much more. That's the reason why the clip-children flag is on by default.
Seem like a lot of work is involved to make this behavior go away to me.
if you want it comfortable to use and flickerfree, yes ;)
Search the forum for wxSkin, maybe it does what you need.
I use WXDevCPP and the flag I turn on is the wxClipChildren and I use that to stop the flicker (read up on it before I started using it) so I was backwards when I said I turned on the noclip because I am actually turning on the clip (heheh). Anyways, I wonder why it is so much work to do this when it could be a simple flag? Use a png, or anything with an alpha mask, and it conforms to the alphamask transparency.

Post Reply