Alpha painting inside a bitmap?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Alpha painting inside a bitmap?

Andrew Stone
Hi all,

It seems like there should be an easy answer to this, but I've
searched for about a day and can't find one.  I want to paint inside a
bitmap preserving the alpha channel so that later I can composite this
bitmap onto another surface with Alpha blending.  I need to use cairo
(for rsvg) and the normal GraphicsContext and/or GCDC but I can't
figure out how to get a handle to these without going through a
standard DC (wxMemoryDC).  For example, to get the cairo handle, I
think I need to use: wx.lib.wxcairo.ContextFromDC().  For
GraphicsContext it looks like there is a "Create(dc)" function

But as soon as I select the bitmap into the DC
(dc.SelectObject(mybitmap)), it turns off the Alpha channel in the
bitmap!

Thanks in advance for any help!

Andrew

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|

Re: Alpha painting inside a bitmap?

Robin Dunn
On 11/9/11 6:36 AM, GAndrewStone wrote:

> Hi all,
>
> It seems like there should be an easy answer to this, but I've
> searched for about a day and can't find one.  I want to paint inside a
> bitmap preserving the alpha channel so that later I can composite this
> bitmap onto another surface with Alpha blending.  I need to use cairo
> (for rsvg) and the normal GraphicsContext and/or GCDC but I can't
> figure out how to get a handle to these without going through a
> standard DC (wxMemoryDC).  For example, to get the cairo handle, I
> think I need to use: wx.lib.wxcairo.ContextFromDC().  For
> GraphicsContext it looks like there is a "Create(dc)" function
>
> But as soon as I select the bitmap into the DC
> (dc.SelectObject(mybitmap)), it turns off the Alpha channel in the
> bitmap!

I don't think that wx.MemoryDC should be doing that.  Please create a
small runnable sample that shows the problem and I'll try to dig a
little deeper into it.  Also, which platform and version are you using?
http://wiki.wxpython.org/MakingSampleApps

If you want to use just Cairo then you can create a Cairo ImageSurface
from the wx.Bitmap with wx.lib.wxcairo.ImageSurfaceFromBitmap.  You can
then use the cairo module to create a context that draws to that
surface.  There is also a function to convert the surface back to a
wx.Bitmap.

In 2.9.2.4 you should be able to make a wx.GrpahicsContext from that
cairo context on Windows and GTK.  It will be possible on Mac too but
the code for dynamically loading the cairo lib hasn't been done there yet.

In 2.9.3 it will be possible to make a wx.GraphicsContext that draws to
a wx.Image, (so no wx.MemoryDC required) although I haven't tried it yet
so I don't know if there are any limitations.


--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|

Re: Alpha painting inside a bitmap?

Kevin Ollivier-5
In reply to this post by Andrew Stone
Hi Andrew,

On Nov 9, 2011, at 6:36 AM, GAndrewStone wrote:

> Hi all,
>
> It seems like there should be an easy answer to this, but I've
> searched for about a day and can't find one.  I want to paint inside a
> bitmap preserving the alpha channel so that later I can composite this
> bitmap onto another surface with Alpha blending.  I need to use cairo
> (for rsvg) and the normal GraphicsContext and/or GCDC but I can't
> figure out how to get a handle to these without going through a
> standard DC (wxMemoryDC).  For example, to get the cairo handle, I
> think I need to use: wx.lib.wxcairo.ContextFromDC().  For
> GraphicsContext it looks like there is a "Create(dc)" function
>
> But as soon as I select the bitmap into the DC
> (dc.SelectObject(mybitmap)), it turns off the Alpha channel in the
> bitmap!

I'm not sure if this is applicable to wxPython, but I've run into an issue in wxWidgets C++ apps on Windows where if something else has a reference to a wx.Bitmap object that you pass to dc.SelectObject, it actually makes a copy of the internal bitmap data. And, when it makes that copy, it does so in a way that strips the alpha channel out. This is a bug in wxWidgets, and though I tried to code up a fix, it was starting to turn into a major project and it was a lot simpler just to simply ensure nothing else had a reference to the wxBitmap before calling SelectObject on it. ;-)

Really not sure if this is applicable to your case or wxPython in general, but I thought I'd mention it, because it's the sort of bug that would be really hard to trace back if you aren't able to poke around under the hood (or even if you areā€¦ that one gave me a few good WTF moments while debugging ;-).

Regards,

Kevin

> Thanks in advance for any help!
>
> Andrew
>
> --
> To unsubscribe, send email to [hidden email]
> or visit http://groups.google.com/group/wxPython-users?hl=en

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|

Re: Alpha painting inside a bitmap?

Andrew Stone
In reply to this post by Robin Dunn
Hi Robin,
Thanks for your suggestions.  I may be able to use the Cairo image
surface... initially I did not think of that because I thought that
the conversion might be slow.

Here's a test case; I may have followed "MakingSampleApps" too
literally; I don't even bother to pop up a window or display the
bitmap.  But more verbose versions are available that do that and show
no transparency.  I just do dc.SelectObject and bitmap.HasAlpha() goes
False.  The output I'm seeing is:

2.8.12.1 (gtk2-unicode)
Alpha:  True
Alpha:  False
Alpha:  False

Here is the script:

import wx

def Test():
  print wx.version()
  app = wx.App()
  bitmap = wx.EmptyBitmapRGBA(64,64, red=0, green=0, blue=0,
alpha=255)  # or wx.EmptyBitmap(64,64,32)

  dc = wx.MemoryDC()
  print "Alpha: ", bitmap.HasAlpha()
  dc.SelectObject(bitmap)
  print "Alpha: ", bitmap.HasAlpha()
  dc.SelectObject(wx.NullBitmap)
  print "Alpha: ", bitmap.HasAlpha()


if __name__ == "__main__":
  Test()

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en
Reply | Threaded
Open this post in threaded view
|

Re: Alpha painting inside a bitmap?

Robin Dunn
On 11/10/11 1:53 PM, GAndrewStone wrote:

> Hi Robin,
> Thanks for your suggestions.  I may be able to use the Cairo image
> surface... initially I did not think of that because I thought that
> the conversion might be slow.
>
> Here's a test case; I may have followed "MakingSampleApps" too
> literally; I don't even bother to pop up a window or display the
> bitmap.  But more verbose versions are available that do that and show
> no transparency.  I just do dc.SelectObject and bitmap.HasAlpha() goes
> False.  The output I'm seeing is:
>
> 2.8.12.1 (gtk2-unicode)
> Alpha:  True
> Alpha:  False
> Alpha:  False
>

I haven't looked too closely at this yet, but the good news is that the
problem is gone in the 2.9 series.

--
Robin Dunn
Software Craftsman
http://wxPython.org

--
To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wxPython-users?hl=en