[cairo] Color-Tinting a surface with alpha channel
Simon Schneegans
code at simonschneegans.de
Tue Dec 22 06:18:26 UTC 2020
Dear all!
I want to use Cairo to colorize / tint a RGBA Pixbuf with a given RGB
(potentially RGBA) color. It would be great if this could be achieved
with normal operators since rolling my own loop over all pixels is too
slow as I am writing a GNOME Shell extension and am therefore bound to
GJS. As Cairo.Operator.MULTIPLY uses normal OVER-alpha-blending, the
code below does not really multiply the image with the given color. E.g.
black semi-transparent areas will actually become tinted as well!
// We first draw the image in normal colors with
Cairo.Operator.OVER.
ctx.setOperator(Cairo.Operator.OVER);
Gdk.cairo_set_source_pixbuf(ctx, image, 0, 0);
ctx.paint();
const pattern = ctx.getSource();
// Then we use Cairo.Operator.MULTIPLY to colorize the image.
We use ctx.mask()
// in order to maintain the alpha channel of the original image.
ctx.setSourceRGBA(color.red / 255, color.green / 255,
color.blue / 255, color.alpha / 255);
ctx.setOperator(Cairo.Operator.MULTIPLY);
ctx.mask(pattern);
If anybody knows how to do a simple result.rgba = first.rgba *
second.rgba in Cairo, please let me know I think the difficulty boils
down to the fact that Cairo uses pre-multiplied alpha but the use-case
of colorizing a RGBA image seems quite common to me. I hope that ther is
a solution I am simply not aware of.
Thank you!
Simon
More information about the cairo
mailing list