Cairo is great for rendering stuff, but doesn't give you many options to export your data. The Python Image Library has good options to save stuff. The problem I ran into is that I have a ARGB32 pycairo surface, and PIL doesn't support ARGB32. It supports RGBA instead. After much experimentation, I came up with the following piece of code, using numpy to solve this problem:

def pilImageFromCairoSurface( surface ):
cairoFormat = surface.get_format()
if cairoFormat == cairo.FORMAT_ARGB32:
pilMode = 'RGB'
# Cairo has ARGB. Convert this to RGB for PIL which supports only RGB or
argbArray = numpy.fromstring( surface.get_data(), 'c' ).reshape( -1, 4 )
rgbArray = argbArray[ :, 2::-1 ]
pilData = rgbArray.reshape( -1 ).tostring()
raise ValueError( 'Unsupported cairo format: %d' % cairoFormat )
pilImage = PIL.Image.frombuffer( pilMode,
( surface.get_width(), surface.get_height() ), pilData, "raw",
pilMode, 0, 1 )
pilImage = pilImage.convert( 'RGB' )
return pilImage