[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