Почему Cairo портит мои цвета?

#python #image #image-processing #cairo #pycairo

#python #изображение #обработка изображений #cairo #pycairo

Вопрос:

 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
  

Я могу использовать surface.write_to_png , чтобы заставить его работать, но мне было интересно, есть ли способ сделать это без необходимости сохранять его в файл. Я вспомнил, что использовал это раньше, но это было для черно-белых изображений, что объясняет, почему раньше у меня не было проблем.

Ответ №1:

Характер изменения показывает нам, что синий и красный каналы на изображении были заменены. В данном случае это означает, что cairo сохраняет пиксельные данные в памяти в порядке «Синий Зеленый Красный Альфа», а не «Красный Зеленый синий Альфа».

К счастью, Python’s PIL предлагает поддержку этой инверсии: просто передайте «BGRA» в качестве параметра mode в raw-декодер (вместо второго «RGBA» при вызове функции).

Кроме того, обратите внимание, что вам не нужно открывать изображение с помощью PIL — cairo загружает его напрямую, и вы можете получить размер из 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')