[cairo] Color-Tinting a surface with alpha channel

Simon Schneegans code at simonschneegans.de
Fri Dec 25 20:09:57 UTC 2020

Thank you so much for your time and effort! Especially at this time of 
the year :)

But I am afraid your method does not yet accomplish my goal. At first I 
was totally convinced by the image your code produced and ported the 
code to GJS. Then I realized that the result is actually pretty similar 
to me method (e)! The checkerboard made this very difficult to spot in 
the first place. But if you replace the checkerboard with a white 
background you receive this image:

If you use e.g. Gimp to look at the color channels you see that there is 
a darkening in the red channel which shouldn't be there:

If you modify the color of the upper gradient in your input() function 
to produce the desired image directly, you get this:

Not only the upper, but also the bottom gradient looks quite different 

Do you have an idea how to approach this?

Again, thank you so much - and a happy Christmas!

On 25.12.20 14:07, Uli Schlachter wrote:
> Am 24.12.20 um 21:10 schrieb Simon Schneegans:
>> Hi Uli,
>> thank you for the kind reply!
>>> Could you explain a bit more what exactly you want to achieve? E.g.,
>>> what should happen when tinting with r=0.5, g=1, b=0, a=0.5 to colors
>>> such as full red and... basically all the other colors.
>> I think you understood my issue very well, but I will try to explain it
>> with more examples.
> Thanks a lot. The image helped. My checkerboard pattern does not look as
> well as yours, but attached is a program which seems to do what you
> want. You want to look at the function tint().
> It works like this:
> A given surface is split into its color component and alpha channel by
> copying it to a color-only (CAIRO_CONTENT_COLOR / CAIRO_FORMAT_RGB24)
> and an alpha-only (CAIRO_CONTENT_ALPHA / CAIRO_FORMAT_A8) surface,
> respectively. This is done via the function copy_with_content() in the
> attached program. The color-only part is multiplied with your color via
> The multiplication result is then copied back to the target surface. By
> doing this with cairo_mask(cr,
> the_alpha_channel_of_the_original_surface), the alpha channel of the
> original surface is recombined with the color components.
> Since you also asked how to add tint with an ARGB-color: You can modify
> the alpha-only surface before re-applying it. I think the following
> should work (well, you have to extract the underlying cairo_surface_t
> from the cairo_pattern_t in the code, but I bet you can figure out how
> to do that):
>   cairo_t *cr = cairo_create(alpha);
>   cairo_set_source_rgba(cr, 0, 0, 0, alpha_factor);
>   cairo_set_operator(cr, CAIRO_OPERATOR_IN);
>   cairo_paint(cr);
>   cairo_destroy(cr);
> Cheers,
> Uli
> P.S.: Error handling left as an exercise for the reader. I am not sure
> if ignoring the return value of cairo_pattern_get_surface() really is a
> good idea...

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20201225/5bbbc8c9/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dgifmblbokgfpkoh.png
Type: image/png
Size: 424 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20201225/5bbbc8c9/attachment-0003.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: baalodpcnemiemgf.png
Type: image/png
Size: 3851 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20201225/5bbbc8c9/attachment-0004.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bbkldjepikpokjmj.png
Type: image/png
Size: 335 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20201225/5bbbc8c9/attachment-0005.png>

More information about the cairo mailing list