[wxPython-users] using wxImage in C++ python extension

Christopher Barker Chris.Barker at noaa.gov
Wed Aug 16 15:42:51 PDT 2006


Josiah Carlson wrote:
> Ultimately, if a user wants to use a buffer without copying, one should
> be sure that the buffer cannot be moved in memory by design (string) or
> by convention. =


To wrap this up even more, and to make sure I get it... (is the OP even =

paying attention anymore?).

The buffer object itself does not manage memory, it is a container for a =

pointer. Which ever object first allocates the memory that the buffer is =

using is responsible for deleting it.

In the OP's case, I think the goal was to create the data for a wxImage =

in a C/C++ extension, then have a wxImage use it. One option is to use =

the wxWidgets C++ API to create a wxImage, then use the wxPython Swig =

stuff to wrap it. This means that the extension would have to be =

compiled against the right version of wxWidgets, and use all the right =

SWIG stuff.

The alternative is for the OP to create a buffer object that points to =

the data, and just pass that in to wx.Image.SetDataBuffer, all in =

Python, thus making sure that the object that manges the data stays =

around as long as the wx.Image does.

This is also relevant to the Matplotlib wx wrappers, which now need to =

be compiled against wx to get optimized passing of data form the Agg =

buffer to wxImage. I think we could use this technique instead, and then =

it's be easier to build MPL, and have it work with multiple versions of wx.

I've also used this to create a wx.Image from the data from a GDAL =

(geo-referenced raster maps) image. I had been creating a string from =

the data, then a wx.Image from the string, which really was one copy too =

many. Now I populate the wx.Image with SetDataBuffer, and make sure I =

keep a reference to the string around.

Which brings me to the next point:

I've written a tiny little factory function that creates a wx.Image with =

  the data from a buffer, with a reference to the buffer. That way, the =

buffer object won't get deleted until after the wx.Image is deleted. Of =

course, as Josiah has made clear, that doesn't guarantee anything if the =

  object you pass it doesn't keep that memory around, but it's a start, =

and should work at least for the common case of a simple Python string.

I first thought to subclass wx.Image, and make a version that is =

identical, except that it holds a reference to the buffer object that is =

used to create it. However, I couldn't' figure out how to do it, because =

it seems wxImages are all created by different factory functions, so I =

can't just override the __init__. Can I do this with some kind of =

judicious calling of wx.Image.__new__?

I've enclosed a simple test of my ImageFromBuffer function. It seems to =

work. If I don't put the reference to the string in there, I get some =

garbage. If I do, the image looks fine. would this be a worthwhile small =

addition to wxPython?

-Chris







-- =

Christopher Barker, Ph.D.
Oceanographer
                                     		=

NOAA/OR&R/HAZMAT         (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ImageBuffer.py
Type: text/x-python
Size: 2452 bytes
Desc: not available
Url : http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/20060=
816/fdebb3d6/ImageBuffer.py


More information about the wxpython-users mailing list