Page 1 of 1
draw transparent image over another image
Posted: Wed Feb 04, 2009 4:40 am
by manteez
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
the result that I want is like this
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
Posted: Thu Feb 05, 2009 9:56 pm
by Disch
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.
Posted: Fri Feb 06, 2009 12:50 am
by Auria
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.
Posted: Fri Feb 06, 2009 2:07 am
by Disch
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.
Posted: Sun Jul 26, 2009 9:51 am
by Dark Alchemist
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):
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.
Posted: Tue Jul 28, 2009 1:54 pm
by leiradella
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
Posted: Tue Jul 28, 2009 4:43 pm
by tierra
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.
Posted: Tue Jul 28, 2009 7:51 pm
by leiradella
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
Posted: Wed Jul 29, 2009 8:50 am
by doublemax
additionally, search the forum for "msw.window.no-clip-children" which will explain why you get the observed behavior.
Posted: Wed Jul 29, 2009 5:57 pm
by Dark Alchemist
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.
Posted: Wed Jul 29, 2009 6:02 pm
by leiradella
Maybe SDL is better suited for what you're doing?
Cheers,
Andre
Posted: Wed Jul 29, 2009 6:08 pm
by doublemax
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.
Posted: Wed Jul 29, 2009 7:20 pm
by Dark Alchemist
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.