[cairo] pycairo and PIL

Steve Chaplin stevech1097 at yahoo.com.au
Thu Sep 22 09:25:21 PDT 2005


On Thu, 2005-09-22 at 08:49 -0500, James Evans wrote:
> Actually, that wasn't supposed to be in the patch. If you look, the #if 0
> (line 431) is still in effect. This is a relic of my first attempt. Both
> hunk #4 and #5 shouldn't have been included.
> 
> I agree that if you want to enable this function, a PyBufferObject should
> be passed in rather than a char *,int pair.
> 
> I backed off using image_surface_create_for_data and modified
> image_surface_new so that I didn't have 2 types of surfaces, one I could
> get the data from (created with image_surface_create_for_data) and one I
> couldn't (created with image_surface_new). I didn't have need to pass in
> an existing buffer to use as the surface, although come to think of it I
> have a personal project that could use that funcationalty....
> 
> Are you thinking that the caller of image_surface_create_for_data should
> use it like this:
> 
> import cairo
> import Image
> 
> python_image = Image.open("background.png")
> (Width,Height) = python_image.size
> image_buffer = python_image.tostring()
> cairo_image = cairo.ImageSurface.create_for_data(image_buffer,
> cairo.FORMAT_ARGB32, Width, Height)
> 
> It does seem like that would be useful. I don't think I'll have time to
> look at this until this weekend. Would you like me to take a shot at it?
> 
> Thanks,
> 
> james

Unfortunately a string is no good, as its not writable.
The cairo.ImageSurface.create_for_data() line gives the error:
TypeError: Cannot use string as modifiable buffer.
The 'data' argument must be a writable object supporting the python
buffer protocol.

I was not necessarily thinking of how best to interface to PIL, I was
thinking that cairo_image_surface_create_for_data() is a function that
I've not been able to 'wrap' in python due to a referencing problem, and
your patch gave me the idea of how to finally get it working.

I've created tests (in pycairo/test) that work with a Python array, a
Numeric array, and a numarray.
The array test is:

#!/usr/bin/env python

import array
import math

import cairo

width, height = 30*16, 30*9

data = array.array('c', 'a' * width * height * 4)
stride = width * 4
surface = cairo.ImageSurface.create_for_data (data, cairo.FORMAT_ARGB32,
                                              width, height, stride);
del data  # to test that create_for_data() references 'data'
ctx = cairo.Context (surface)

ctx.scale (width, height)

pat = cairo.LinearGradient (0.0, 0.0, 0.0, 1.0)
pat.add_color_stop_rgba (1, 0, 0, 0, 1)
pat.add_color_stop_rgba (0, 1, 1, 1, 1)

ctx.rectangle (0,0,1,1)
ctx.set_source (pat)
ctx.fill ()

pat = cairo.RadialGradient (0.45, 0.4, 0.1,
                            0.4,  0.4, 0.5)
pat.add_color_stop_rgba (0, 1, 1, 1, 1)
pat.add_color_stop_rgba (1, 0, 0, 0, 1)

ctx.set_source (pat)
ctx.arc (0.5, 0.5, 0.3, 0, 2 * math.pi)
ctx.fill ()

surface.write_to_png ('for_data1.png')


Steve

Send instant messages to your online friends http://au.messenger.yahoo.com 


More information about the cairo mailing list