How do I maintain the mask of a bitmap correctly for use with wxDC.Blit()?

I'm trying to implement a drag and drop function to allow users to grab an
image from a palette and drop it onto a location in a canvas. The original
images can come from bmp or gif files that have a transparent color set.

Once the original bitmap in the palette is created, transparency info for
images from bmp files is already lost; and although images from gif display
correctly (i.e. transparent where they should be) they also have no mask
object associated with the wxBitmap.

The drop operation creates a copy of the wxBitmap object, so I need to
create a mask. Even when I hardcode in a mask color (presuming it is
white for instance) the image does not Blit correctly even with useMask
set to 1. The underlying pixels in the destination DC are overwritten even
by pixels in the source DC that are masked.

I'm really at a loss here. It seems like I'm just not understanding something
about either wxBitmap or wxMask.

···

------------------------------------------------------------
Jeff Kotula
jkotula@earthlink.net

Jeff Kotula wrote:

I'm trying to implement a drag and drop function to allow users to grab an
image from a palette and drop it onto a location in a canvas. The original
images can come from bmp or gif files that have a transparent color set.

BMP files do not have a transparency attribute. The way it is usually done is by using a hard-coded colour value (#C0C0C0 I think, or maybe it was magenta?) in the .bmp that apps are supposed to treat as transparent. Thanks to MS for this lovely feature.

Once the original bitmap in the palette is created, transparency info for
images from bmp files is already lost; and although images from gif display
correctly (i.e. transparent where they should be) they also have no mask
object associated with the wxBitmap.

If transparency is drawn correctly, then there is a mask. Does bitmap.GetMask() not return something? If not maybe it is only generating the internal representation of it...

The drop operation creates a copy of the wxBitmap object, so I need to
create a mask. Even when I hardcode in a mask color (presuming it is
white for instance) the image does not Blit correctly even with useMask
set to 1. The underlying pixels in the destination DC are overwritten even
by pixels in the source DC that are masked.

Internally a wxBitmap with a mask is stored as two separate bitmaps (HBITMAP on Windows) but my guess is that only the handle for the bitmap is made available in the wxBitmapDataObject. I'm not sure if there is a standard way to pass both or not. A bug report about this may turn up some more info from those that know.

I'm really at a loss here. It seems like I'm just not understanding something
about either wxBitmap or wxMask.

An ugly workaround that pops into mind is -- since you appear to be handling both ends of the DnD in your app(s) -- to not use wxBitmapDataObject at all. Instead convert the image to a PNG in a string (like what the img2py tool does) and pass the string as a custom data object. The receiving end could then convert it back to a wx.Bitmap using wx.ImageFromStream. The mask shoudl come across intact like this.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!