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

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

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.

···

On 3/11/10 2:59 PM, Neurocomp wrote:

--
Robin Dunn
Software Craftsman

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.Barker@noaa.gov

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

Neurocomp wrote:

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

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

What is it you are trying 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.Barker@noaa.gov

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.

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,

-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.Barker@noaa.gov

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)

···

On Mar 14, 5:07 pm, Christopher Barker <Chris.Bar...@noaa.gov> wrote:

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,

-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.Bar...@noaa.gov

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!!! :wink:

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.Barker@noaa.gov

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 =*[

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,

-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.Barker@noaa.gov