Alpha painting inside a bitmap?

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

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? MakingSampleApps - wxPyWiki

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.

···

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!

--
Robin Dunn
Software Craftsman

Hi Andrew,

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. :wink:

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

···

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

Thanks in advance for any help!

Andrew

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

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()

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

···

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

--
Robin Dunn
Software Craftsman