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

Ken McIvor wrote:

    >>
    >> a wxBitmap is the same format as the native rendering
    >> system. While most systems use 24b RGB (or 32b RGBA), people
    >> can still run displays at 16bpp or whatever, so it's still
    >> needed.

    > I can understand why it's still necessary, although it's nice
    > to sometimes pretend that everyone's running 24-bit color
    > displays. I hope I didn't sound too judgemental!

    >>> I don't think we're going to be able to get performance
    >>> similar to that of the accelerator using straight Python code
    >> But whether it's Python or C++, you still need to do the
    >> Image->Bitmap conversion -- so if we can get rid of the data
    >> copying from Agg buffer to wxImage in Python, we don't need
    >> C++.

    > I think we got some wires crossed at some point in the
    > conversation, although it could be that I'm wearing the
    > Stupid Hat today. I was talking about the
    > image-from-a-buffer business not helping us with WX 2.4/2.6
    > due to the RGBA to RGB conversion.

    >> And it has. For wxPython 2.7 (and now in CVS) there are methods
    >> for dumping 32 bit RGBA data directly into a wxBitmap with no
    >> copying, if the data source is a Python Buffer object. I think
    >> I posted a note about this here yesterday.

    > Yes, you did mention it. I agree completely with this
    > analysis of the situation. When I replied I wasn't thinking
    > in terms of wxPython 2.7.

    >> To really get it to work, the 24bit RGB Agg buffer needs to be
    >> a Python Buffer object -- is it now? I'm sorry I don't have the
    >> time to mess with this now -- maybe some day.

    > I guess Guido lets John borrow his time machine, because
    > RendererAgg appears to already have a buffer_rgba() method.

Guido has been very generous with us :slight_smile:

    >> You can alpha composite into a non-alpha background. You just
    >> lose the alpha there, so that the background couldn't be
    >> alpha-composited onto anything else -- but does it ever need to
    >> be?

    > I thought that the buffer's accumulated alpha played a role
    > in compositing new pixels onto it, but I apparently
    > misunderstood.

It does: here is agg's rgba pixel blending routing

        static AGG_INLINE void blend_pix(value_type* p,
                                         unsigned cr, unsigned cg, unsigned cb,
                                         unsigned alpha,
                                         unsigned cover=0)
        {
            calc_type r = p[Order::R];
            calc_type g = p[Order::G];
            calc_type b = p[Order::B];
            calc_type a = p[Order::A];
            p[Order::R] = (value_type)(((cr - r) * alpha + (r << base_shift)) >> base_shift);
            p[Order::G] = (value_type)(((cg - g) * alpha + (g << base_shift)) >> base_shift);
            p[Order::B] = (value_type)(((cb - b) * alpha + (b << base_shift)) >> base_shift);
            p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift));
        }

    > Images. Anyway, if the buffer's alpha channel isn't used,
    > then the whole situation does seem a bit odd. Could the
    > information be retained for PNGs or something?

It is useful to store the final pixel buffer (eg in a PNG) as RGBA
because some people like to have some parts of their figure
transparent to composite the figure with other images.

JDH

···

On 08/31/06 13:43, Christopher Barker wrote:

John Hunter wrote:

It is useful to store the final pixel buffer (eg in a PNG) as RGBA because some people like to have some parts of their figure transparent to composite the figure with other images.

fair enough, and that's probably a really cool feature when you need it!

ken wrote:

I was talking about the image-from-a-buffer business not helping us
with WX 2.4/2.6 due to the RGBA to RGB conversion.

But it looks like RendererAgg has this a agg.tostring_rgb() method, so we should be able to do change :

image.SetData(agg.tostring_rgb())

to

image.SetDataBuffer(agg.tostring_rgb())

If we make sure to keepthe string around. I haven't looked at your C++ code, but does it do something faster than RendererAgg.tostring_rgb() ?

Another thing that would be nice (for all Agg back-ends, I imagine), is if we could replace this:

         # agg => rgb -> image => bitmap => clipped bitmap => image
         return wx.ImageFromBitmap(_clipped_image_as_bitmap(image, bbox))

with a RendererAgg._clipped_tostring_rgb(bbox)

So that we don't copy a bunch of RGB data we don't need.

even if we don't do that, I think

_clipped_image_as_bitmap()

could use wx.Image.GetSubImage(), rather than creating a bimtp of the whole thing and blitting. untested code:

def _clipped_image_as_bitmap(image, bbox):
     """
     Convert the region of a wx.Image described by bbox to a wx.Bitmap.
     """
     l, b, width, height = bbox.get_bounds()

     return wx.BitmapFromImage(image.GetSubImage(wxRect((l,b),(w,h))))

> RendererAgg appears to already have a buffer_rgba() method.

So we're all set for wxPython 2.7 -- very nice! I hope it doesn't make a copy.

Is there a numpy_array_rgba method -- that could be nice, and would work as a buffer, too. Maybe when we are ready to dump Numeric and numarray.

-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@...236...