Рисование с одной поверхности на другую поверхность

import cairo
import math

w = 2000
h = 2000

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
ctx = cairo.Context(surface)
ctx.scale(w, h)

surface_path = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
ctx_path = cairo.Context(surface_path)
ctx_path.scale(w, h)

surface_circle = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
ctx_circle = cairo.Context(surface_circle)
ctx_circle.scale(w, h)

""" Lots of function calls that draw paths to surface_path and circles to surface_circle """

ctx.set_source_surface(surface_path, 0, 0)
ctx.paint()
ctx.set_source_surface(surface_circle, 0, 0)
ctx.paint()

surface_path.write_to_png("example.png")
surface_circle.write_to_png("example2.png")
surface.write_to_png("result.png")

Ссылка Imgur на сохраненные изображения

Я пытаюсь скомпилировать две поверхности (одну с линиями, одну с кругами) на одну отдельную поверхность, а затем сохранить ее в файл.

Несмотря на то, что согласно документации должно работать, окончательное изображение оказывается пустым. Я также пытался позвонить flush() на surface_path и surface_circle, но это, похоже, ничего не дало.

Как я могу объединить информацию об изображении в surface_circle (example2.png) поверх surface_path (example.png), а затем вывести ее в файл?


person Sky    schedule 08.02.2014    source источник
comment
Я не эксперт по каиру, но думаю, вам нужна маска. Например, вы выбираете источник и рисуете линию. По пути линии источник копируется в место назначения. Если вы ничего не рисуете, ничего не переносится. Я бы посоветовал вам нарисовать большой прямоугольник размером с изображение. См. cairographics.org/tutorial/#L1drawing.   -  person Cilyan    schedule 08.02.2014
comment
ctx.set_source_surface(surface_path, 0, 0) ctx.rectangle(0, 0, 1, 1) ctx.fill() ctx.set_source_surface(surface_circle, 0, 0) ctx.stroke() ctx.rectangle(0, 0, 1, 1) ctx.fill() ctx.stroke() Я попробовал этот код, но он по-прежнему не работает.   -  person Sky    schedule 08.02.2014


Ответы (1)


Попробуйте вызвать ctx.identity_matrix() перед несколькими последними вызовами paint().

Как и сейчас, благодаря вашему вызову ctx.scale(w, h) вы получаете только верхние левые пиксели этих других поверхностей, увеличенные для заполнения всей целевой поверхности.

person Uli Schlachter    schedule 08.02.2014
comment
Похоже, это сработало. Однако я не совсем понимаю, что делают scale() и identity_matrix() :( Не могли бы вы кратко объяснить/связать меня с ресурсом, который объясняет? - person Sky; 09.02.2014
comment
Хорошо, масштаб применяет масштабирование ко всем следующим операциям. Когда вы выполняете масштабирование (a, b), все координаты, которые вы будете использовать позже, будут умножены на a или b соответственно. Иными словами, он делает вид, что поверхность, которую вы рисуете, имеет размер только 1/a, 1/b. В вашем коде он масштабирует поверхность так, что все координаты находятся в диапазоне от 0 до 1 вместо 0 и w или h. Все, что делает identity_matrix(), это сбрасывает все масштабирование, переводы и т. д. и вообще не возвращает никаких преобразований. Некоторые документы см. на cairographics.org/manual/cairo-Transformations.html. - person Uli Schlachter; 09.02.2014