Как изменить исходный цвет контекста cairo для изображений в градациях серого

Я пытаюсь создать изображения в оттенках серого с помощью Cairo, однако у меня возникают проблемы с контролем интенсивности пикселей пера.

Например, в цветном изображении RGB я бы использовал этот код, чтобы нарисовать фон красным оттенком с интенсивностью пикселей 127 в красном канале.

surface = cairo.ImageSurface(cairo.FORMAT_RGB24, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
ctx.set_source_rgb(.5, 0, 0)
ctx.rectangle(0, 0, WIDTH, HEIGHT)
ctx.fill()

Я не могу найти эквивалентный код для изображения в градациях серого. Я не могу просто использовать альфа-канал, потому что тогда я не могу рисовать круги поверх прямоугольников. Например, возьмите приведенный ниже фрагмент кода, где я хотел бы иметь:

  • Серый фон
  • Черный круг на сером фоне

    surface = cairo.ImageSurface(cairo.FORMAT_A8, WIDTH, HEIGHT) ctx = cairo.Context(surface) ctx.set_source_rgba(0, 0, 0, 0.5) ctx.rectangle(0, 0, WIDTH, HEIGHT) ctx.fill() ctx.set_source_rgba(0, 0, 0, 0.0) ctx.arc(WIDTH//2, HEIGHT//2, r, 0, 2*math.pi) ctx.fill()

В приведенном выше коде черный кружок не появится, потому что его альфа-канал ниже серого фона. Как я могу это исправить?


person Arash Outadi    schedule 24.09.2018    source источник
comment
Какова именно ваша цель во втором примере? Вы используете set_source_rgb, поэтому здесь альфа=1. Итак, вы просто заполняете поверхность не-альфа. Возможно, ctx.set_operator(cairo.OPERATOR_SOURCE) помогает вам/делает то, что вы хотите?   -  person Uli Schlachter    schedule 24.09.2018
comment
Привет, @UliSchlachter, я обновил свой пост, чтобы содержать больше информации о том, чего я пытаюсь достичь, в отношении ctx.set_operator, возможно, OPERATOR_CLEAR может сработать. Я попробую и вернусь к вам. Я не знал о методе set_operator, спасибо, что напомнили!   -  person Arash Outadi    schedule 24.09.2018


Ответы (1)


В приведенном выше коде черный кружок не появится, потому что его альфа-канал ниже серого фона.

Оператор по умолчанию OVER, который накладывает вещи. Если у вас есть какое-то полностью прозрачное наложение, то это наложение будет невидимым. Итак, это не из-за нижнего альфа-канала. Если бы у вас был немного более высокий альфа-канал, скажем, 0,5 и 0,1, результатом был бы альфа-канал со значением около 0,6 в результирующем изображении.

Как я могу это исправить?

surface = cairo.ImageSurface(cairo.FORMAT_A8, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
// I added the following line, but I am not sure about the syntax.
// In C, this would by cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
ctx.set_operator(cairo.OPERATOR_SOURCE)
ctx.set_source_rgba(0, 0, 0, 0.5)
ctx.rectangle(0, 0, WIDTH, HEIGHT)
ctx.fill()
ctx.set_source_rgba(0, 0, 0, 0.0)
ctx.arc(WIDTH//2, HEIGHT//2, r, 0, 2*math.pi)
ctx.fill()
person Uli Schlachter    schedule 25.09.2018
comment
Потрясающе, большое спасибо. Это именно то, что я хотел! Всем, кому интересно, вы можете прочитать больше об операторах здесь: cairographics.org/operators - person Arash Outadi; 25.09.2018