Transparent bitmap drawing issue

Using wxPython 2.8.9.1 on Linux (Debian).

I can't draw on a transparently initialised bitmap. The following code :

···

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 0)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
#--------------------------------------------

produces "test_out.png" which is totally transparent (no red square).
The following code :

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 255)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
#--------------------------------------------

produces "test_out.png" which is black opaque with a little red square.

It looks like the drawing primitives don't affect the alpha layer.
Shouldn't they ?

David.

Hi David,

···

On Wed, Oct 8, 2008 at 11:21 AM, David Libault wrote:

Using wxPython 2.8.9.1 on Linux (Debian).

I can't draw on a transparently initialised bitmap. The following code :

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 0)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
#--------------------------------------------

produces "test_out.png" which is totally transparent (no red square).
The following code :

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 255)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
#--------------------------------------------

produces "test_out.png" which is black opaque with a little red square.

It looks like the drawing primitives don't affect the alpha layer.
Shouldn't they ?

Does anything change if you add this line:

dc.SelectObject(wx.NullBitmap)

*before* converting the bitmap to an image?

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

The following code :

···

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 0)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

dc.SelectObject(wx.NullBitmap)
image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
I also tried on XP
#------------------------------------------------------

behaves exactly the same way.

I also want to point out that this code works as expected on XP.

Regards,

David.

2008/10/8 Andrea Gavana <andrea.gavana@gmail.com>:

Hi David,

On Wed, Oct 8, 2008 at 11:21 AM, David Libault wrote:

Using wxPython 2.8.9.1 on Linux (Debian).

I can't draw on a transparently initialised bitmap. The following code :

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 0)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
#--------------------------------------------

produces "test_out.png" which is totally transparent (no red square).
The following code :

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 255)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
#--------------------------------------------

produces "test_out.png" which is black opaque with a little red square.

It looks like the drawing primitives don't affect the alpha layer.
Shouldn't they ?

Does anything change if you add this line:

dc.SelectObject(wx.NullBitmap)

*before* converting the bitmap to an image?

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Hello,

The following code :

#--------------------------------------------
import wx

app = wx.PySimpleApp()
bitmap = wx.EmptyBitmapRGBA(100, 100, 0, 0, 0, 0)

dc = wx.MemoryDC()
dc.SelectObject(bitmap)
dc.SetBrush(wx.Brush("Red"))
dc.DrawRectangle(10, 10, 20, 20)

dc.SelectObject(wx.NullBitmap)
image = bitmap.ConvertToImage()
image.SaveFile('test_out.png', wx.BITMAP_TYPE_PNG)
I also tried on XP
#------------------------------------------------------

behaves exactly the same way.

I also want to point out that this code works as expected on XP.

Regards,

I have found that with the gtk port that in order to get transparency in a bitmap when drawing a DC that I need to use an opaque bitmap, draw in it, then convert to an Image and manually set the pixels that I want to be transparent, transparent 1 by 1. In order to make this workaround hack work in more cases, when drawing the bitmap first draw the whole background in a color that is not going to be used the rest of the bitmap so that it is easy to find what should be transparent later.

# HACK:
timg = bitmap.ConvertToImage()
if not timg.HasAlpha():
     timg.InitAlpha()
for y in xrange(timg.GetHeight()):
     for x in xrange(timg.GetWidth()):
           pix = wx.Colour(timg.GetRed(x, y),
                                     timg.GetGreen(x, y),
                                     timg.GetBlue(x, y))
            if pix == MyBackgroundColour:
                  timg.SetAlpha(x, y, 0)
bitmap = timg.ConvertToBitmap()

This behavior can also be noticed when drawing on to a bitmap with existing transparency. If you have for example a 32x32 pixel bitmap that has a solid 16x16 square in the middle and draw a line from 0 - 32 across it only the portion of the line that is on the square will be visible. I believe this is an error in the drawing code on gtk and this behavior is inconsistent with the other platforms and any bitmap editor program.

I remember some talk about this on wx-dev last winter/spring, can't remember exactly what was said so you may want to search it but for some odd reason I think it was decided not to change this...

Cody

···

On Oct 8, 2008, at 5:56 AM, David Libault wrote: