can wx.Bitmap & wx.Image share pixel data or buffers?

339 views
Skip to first unread message

Neurocomp

unread,
Mar 11, 2010, 5:59:02 PM3/11/10
to wxPython-users
Hi, I've been searching for 3-4 days, on whether wx.Bitmap can share a
pixel buffer with wx.Image, to no avail. I came across
wx.NativePixelData but am not sure whether it can somehow be used with
wx.Image.SetData to associate the wx.Bitmap buffer.
--
I am a novice at python(scipy/numpy/wxpython) but am familiar with
wxwidgets in C++. The app i'm building is for Computational Neuro.-
Vision. Specs:

windows vista-32;
python version 2.5.2;
wxpython - 2.8-msw;
wxwidgets(C++) - 2.8.7;
--
MyApp: For the same buffer data, I require the functionality of
wxDC(via wxMemoryDC) and the SetPixel from wxImage. The reason for the
latter
is that I copy & zoom from a loaded image file into the buffer and it
seems way faster to use SetPixel(x,y,colour) than to use the
combination SetPen/DrawPoint
--
MyCode: currently uses ImageFromBitmap, BitmapFromImage
and have used ConvertTo{Image,Bitmap}, to convert back and forth. For
example:
- I store a bitmap
- convert to image to use setPixel
- copy back to bitmap
- use memoryDC

OR
- I store a image
- use setPixel
- convert to bitmap to use DC
- copy back to image
--
Note: I achieve the effects I desire, but i'm not sure if there are
memory leaks, resource hogging, or unnecessary allocation calls, by
either method converting back and forth using ##From## or
ConvertTo##.
I'm not even sure if i need to call "del" when the buffer is resized
from loading a different image or when the zoom size of single pixel
is different.

I understand the consequence of sharing buffers, in that the class
creating the data must exist longer in memory than the one that just
accesses the buffer.

Any help would be much appreciated, thank you for reading
Jack

Robin Dunn

unread,
Mar 12, 2010, 12:15:10 AM3/12/10
to wxpytho...@googlegroups.com
On 3/11/10 2:59 PM, Neurocomp wrote:
> Hi, I've been searching for 3-4 days, on whether wx.Bitmap can share a
> pixel buffer with wx.Image, to no avail.

No. wx.Bitmap is a platform specific object that wraps whatever is the
native represenation of a bitmap (HBITMAP, pixmap, CGImage, etc.) while
a wx.Image is a platform independent class that manages an array of RGB
bytes and optionally an array of alpha bytes. The memory buffers are
not meant to be compatible at all and most likely can not be.

> I came across
> wx.NativePixelData but am not sure whether it can somehow be used with
> wx.Image.SetData to associate the wx.Bitmap buffer.

No, but it does allow access to the platform specific pixel buffer of
the wx.Bitmap in a platform independent way, a pixel at a time. See the
samples in the demo.


> --
> I am a novice at python(scipy/numpy/wxpython) but am familiar with
> wxwidgets in C++. The app i'm building is for Computational Neuro.-
> Vision. Specs:
>
> windows vista-32;
> python version 2.5.2;
> wxpython - 2.8-msw;
> wxwidgets(C++) - 2.8.7;
> --
> MyApp: For the same buffer data, I require the functionality of
> wxDC(via wxMemoryDC) and the SetPixel from wxImage. The reason for the
> latter

> is that I copy& zoom from a loaded image file into the buffer and it


> seems way faster to use SetPixel(x,y,colour) than to use the
> combination SetPen/DrawPoint
> --
> MyCode: currently uses ImageFromBitmap, BitmapFromImage
> and have used ConvertTo{Image,Bitmap}, to convert back and forth. For
> example:

We also have some helper functions like wx.BitmapFromBuffer and
wx.BitmapFromBufferRGBA that allow you to make a bitmap from any object
that implements the Python buffer interface, such as a numpy array. So
if the kind of pixel manipulations you need to do can be more
efficiently done with a numeric array then that might be something you
want to investigate. There are also some additional wx.Bitmap methods
added by wxPython that can help out with moving data to/from buffers
that work similarly to the factory functions. See the docstrings for
wx.Bitmap.CopyFromBuffer and CopyToBuffer.

Finally, if you switch to using cairo instead of wx.DC's then you can
create a GraphicsBitmap object that does in fact use some buffer (as in
Python buffer interface) object as its pixel storage. (It actually
creates a cairo ImageSurface under the covers.) The GrpahicsBitmap can
be used on a context for drawing or being drawn upon much like you would
do with a wx.Bitmap and a wx.DC, and with the rest of the gaphics
context or cairo API you can make a lot better output than you can with
a wx.DC (alpha is fully supported and drawing is anti-aliased, etc.)
There are also some functions to convert to/from a wx.Bitmap if needed,
and you can also use the cairo APIs to load/save an ImageSurface
directly from/to a PNG file. See wx.lib.wxcairo and wx.lib.graphics.

--
Robin Dunn
Software Craftsman
http://wxPython.org

Chris Barker

unread,
Mar 12, 2010, 2:23:05 PM3/12/10
to wxpytho...@googlegroups.com
Robin Dunn wrote:
> We also have some helper functions like wx.BitmapFromBuffer and
> wx.BitmapFromBufferRGBA that allow you to make a bitmap from any object
> that implements the Python buffer interface, such as a numpy array. So
> if the kind of pixel manipulations you need to do can be more
> efficiently done with a numeric array then that might be something you
> want to investigate.

This is key -- looping in Python to set individual pixels is likely to
be pretty darn slow. What kind of pixel manipulations do you need to do?

-Chris


--
Christopher Barker, Ph.D.
Oceanographer

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

Chris....@noaa.gov

Neurocomp

unread,
Mar 12, 2010, 4:11:51 PM3/12/10
to wxPython-users
Robin, thanks for the reply and suggestion...i'll take a look into
cairo. For my own notes: from what you have written, is it correct to
say wxwidgets/wxpython has no class (without installing another pkg)
that acts directly on wxImage with the functionality of wxDC

regards
Jack

Chris Barker

unread,
Mar 12, 2010, 5:43:35 PM3/12/10
to wxpytho...@googlegroups.com

That's correct, but is it really a problem to do your rendering on
wx.Bitmaps?

What is it you are trying to do?

Neurocomp

unread,
Mar 13, 2010, 7:23:33 PM3/13/10
to wxPython-users
Hi Chris, there are two things that are impl on the data buffer [1]
copying a "zoomed in" subregion of a loaded image file [2] using basic
GDI shape func from wxDC. For the former, i run a double-loop for the
region, getting for EACH pixel, the colour from the imgsrc and copying
a "rect size" to the imgdst. This requires, in the double-loop,
constantly getting the pixel and setting the pixel rect whilst the
colour is changing(based on the loaded image).

To acheive this with wxBitmap/wxDC requires: SetPen/SetBrush/DrawRect
[3 funcs]
Whereas for wxImage requires: SetRGB or SetRGBRect [1 func]

Its too bad that i can't just do bitmap.GetBrush().SetColour(), but it
seems against wx design.

I've looked into subbitmap/subimage but the only way i can think of
mapping 1 pixel to 1 rect
is by interacting with the pixels from either wxBitmap or
wxImage...which to me seems faster with wxImage.

The efficiency may also be due to the fact that i dont' delete
temporary image/bitmap but i haven't tested it yet, which i know is
bad.


Christopher Barker

unread,
Mar 14, 2010, 5:07:07 PM3/14/10
to wxpytho...@googlegroups.com
Neurocomp wrote:
> Hi Chris, there are two things that are impl on the data buffer [1]
> copying a "zoomed in" subregion of a loaded image file [2] using basic
> GDI shape func from wxDC. For the former, i run a double-loop for the
> region, getting for EACH pixel, the colour from the imgsrc and copying
> a "rect size" to the imgdst. This requires, in the double-loop,
> constantly getting the pixel and setting the pixel rect whilst the
> colour is changing(based on the loaded image).

Unless you are working with tiny images, I suspect that python simply
won't be fast enough for this kind of pixel manipulation.

> To acheive this with wxBitmap/wxDC requires: SetPen/SetBrush/DrawRect
> [3 funcs]
> Whereas for wxImage requires: SetRGB or SetRGBRect [1 func]

If you have any hope of doing this in pure python, you are right, you
need to minimize what happens inside that double loop. Aside from the
function calls, DC.DrawRect will draw a rectangle of a particular color,
I don't think you can use it for sub-image, though you can use the
DC.Blit and/or DC.DrawBitmap functions. I'm pretty sure you ca scale
with DC.Blit.

You can also get a SubImage from a wx.Image, and scale that.

In any case, doing pixel-wise manipulations in python will swamp any
time spent converting between wx.Bitmap and wx.Image.

If you can't do what you need with the built-in methods in wx.DC or
wx.Image, then I'd look to another package;

numpy:
You can manipulate arrays of pixels in all kinds of nifty ways with
numpy, and it's easy and efficient to convert to/from numpy arrays and
wx.Bitmap and wx.Image. Look for the ndimage package for numpy add-ons
for image manipulations.


PIL:
The python imaging library provides a lot of nifty image manipulations
as well, and con also be converted to/from the wx classes pretty easily.

HTH,

Neurocomp

unread,
Mar 15, 2010, 4:32:06 PM3/15/10
to wxPython-users
Chris, Thanks for the advice. I'll have to look into the scaling you
mentioned with blit.
The pixel to pixel manipulation between two wx.Image is fairly fast
for what i have now.
Its the conversion between the image & bitmap that i'm worried about,
as i'm not sure when
python deletes buffers and whether i'm leave some dangling.

For this particularly app, I only need simple access to the pixel
buffer and drawing capabilities.
because i'm just testing how to wire up a neural network to the
resulting image buffer. In the end everything will
be moved back to C/C++.

If things are to slow during this testing phase, i'll probably have to
look into using numpy array with
wx.Bitmap (as u have suggested) or bitmap/opencv(camera)

> Chris.Bar...@noaa.gov

Christopher Barker

unread,
Mar 15, 2010, 6:21:19 PM3/15/10
to wxpytho...@googlegroups.com
Neurocomp wrote:
> Its the conversion between the image & bitmap that i'm worried about,
> as i'm not sure when python deletes buffers and whether i'm leave some dangling.

Python's pretty good about memory management -- why are you worries, are
you seeing performance problems? Remember that "premature optimization
is the root of all evil".

> For this particularly app, I only need simple access to the pixel
> buffer and drawing capabilities.
> because i'm just testing how to wire up a neural network to the
> resulting image buffer. In the end everything will
> be moved back to C/C++.

NOO! don't so it!!! ;-)

Seriously, why do C/C++. Do it in Python, and if you have performance
bottleneck, move just that part to C/C++, or, even better, Cython.

> If things are to slow during this testing phase, i'll probably have to
> look into using numpy array with
> wx.Bitmap (as u have suggested) or bitmap/opencv(camera)

numpy arrays work great with Cython -- and as a way to pass data buffers
to C/C++ code.

-Chris

--
Christopher Barker, Ph.D.
Oceanographer

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

Chris....@noaa.gov

Neurocomp

unread,
Mar 16, 2010, 6:01:50 PM3/16/10
to wxPython-users
memmgmt: I guess its just the C/C++ mentality ddelete what you create
=].
hmm if pythons pretty good with mgmt, then i think i'll go back to
what i originally
had which was "image->bitmap->image->bitmap->wxWindow". Don't ask how
i first started with that
but it seemed faster cuz i pass an image between two wxwindows before
impl the zoom factor. Now i pass the bitmap which for some reason
seems slower.

C/C++: ultimately the code will be ported back to C/C++ for HPC
reasons cuz the app is for brain modelling. currently i have only
90-120k neurons, but thats too much to work with when trying to
generate simple edge detection tests so i went with python. However, I
do intend to use either lua/python as the embedded script language.

In your opinion, [1] is it better to have python frontend and C/C++
backend, or [2] embed python and have C/C++ frontend & backend. Also
is cython better than swig (or was it juce...too many libs)? most of
my code is in classes but i had problems with swig that i don't
remmeber.
Might be that i install both MS & cygwin versions =*[

Christopher Barker

unread,
Mar 16, 2010, 7:13:11 PM3/16/10
to wxpytho...@googlegroups.com
Neurocomp wrote:
> i originally
> had which was "image->bitmap->image->bitmap->wxWindow".

I can see how that would look ugly, but it if works, it works. It does
seem a bit much, though. If you post a very trimmed down sample, maybe
one of us will have an alternative suggestion:

http://wiki.wxpython.org/MakingSampleApps

> C/C++: ultimately the code will be ported back to C/C++ for HPC
> reasons cuz the app is for brain modelling.

there are times when that's what you need...

> In your opinion, [1] is it better to have python frontend and C/C++
> backend, or [2] embed python and have C/C++ frontend & backend.

Most people seem to find it easier to use Python on the front end.
Embedding python is a bit of a pain. Ultimately I think the choice is
somewhat dictated by your intended structure:

If you are writing a pretty traditional C++ app, but want to use python
as a scripting language, then you may want to embed it.

If you use Python on the font end, then you are writing a python app,
and essentially extending it with C++ library.

In the end, I think you'll write a lot less C++, and more Python if you
use Python on the front end, and that's a very good thing!

> is cython better than swig (or was it juce...too many libs)?

It's different -- SWIG auto-generates wrapper for C/C++ code. It can
work well (wxPython for example), but it's really kind of like using yet
another language, and you do end up writing a fair bit of interface code
far all but the simple cases.

Cython is a different beast -- it doesn't auto-generate any binding
code. It's kind of like a Python 2 C translator, but you can add
annotations to type variables, and it understands both Python and C
conventions, so it makes it really easy to call C code from Python. Its
C++ support is pretty new, and not as robust, but it is there.

So with Cython, you can write extensions that get compiled to C code
without writing a bit of C, or you can use it to write interfaces to C
code, without having to do any of the tricky reference counting, etc.

I'd say that SWIG has the advantage for two things:

1) wrapping a BIG library that re-uses many of the same classes/data
structures -- you need to write the interface code for each class you
want to use, but then SWIG knows how to use that class everywhere it is
needed -- this has made wxPython possible.

2) wrapping the same C/C++ lib for multiple languages -- SWIG supports
many high level languages, so it can be efficient if you want multiple
wrappers for the same C/C++ lib.


If anyone gets a auto wrapper generator working for Cython, I think that
would be a killer combination! There are folks that have done a bit with
that, but I don't think there is anything at all production ready.

HTH,

Reply all
Reply to author
Forward
0 new messages