Why is Cairo messing with my Colors?
import cairo
from PIL import Image as im
orig_image = im.open('Camilla_Belle_photo_3.jpg') #http://i56.tinypic.com/261i5cn.jpg
surface = cairo.ImageSurface.create_from_png('Camilla_Belle_photo开发者_运维知识库_3.png') #http://i52.tinypic.com/20gmypv.png
context = cairo.Context(surface)
#draw stuff
other_image = im.frombuffer('RGBA', orig_image.size, surface.get_data(), 'raw', 'RGBA', 0, 1)
other_image.save('test.png') #resulting image: http://i51.tinypic.com/farns.png
I can use surface.write_to_png
to get it working, but I was wondering if there was a way to do it without having to save it to a file. I remembered using this before, but it was for black and white images which explains why I had no problems previously.
The nature of the change shows us that the blue and red channels on the image have been swapped. In this case, it means that cairo maintains the pixel data in memory in a Blue Green Red Alpha" order , rather than "Red Green Blue Alpha".
Luckily Python's PIL offer support for that inversion: just pass "BGRA" as the mode parameter to the raw decoder (in place of the second "RGBA" on the function call).
Also, perceie that you don't need to open the image using PIL - cairo loads it directly, and you can fetch the size from cairo's surface:
import cairo
from PIL import Image as im
surface = cairo.ImageSurface.create_from_png('Camilla_Belle_photo_3.png')
context = cairo.Context(surface)
#draw stuff
size = surface.get_width(), surface.get_height()
other_image = im.frombuffer('RGBA', size, surface.get_data(), 'raw', 'BGRA', 0, 1)
other_image.save('test.png')
精彩评论