[cairo] Color-Tinting a surface with alpha channel

Simon Schneegans code at simonschneegans.de
Tue Jan 5 20:15:46 UTC 2021


Hi there!

I searched the internet and played around some more but didn't come any 
closer to a solution. Is it possible to separate / combine RGBA 
channels in cairo? This would help as well! Something like cairo_mask() 
but not only for the alpha channel but for all RGBA channels. I also 
stumbled upon this sentence:

I believe Cairo can do non-premultiplied, by setting the source pattern
and the mask to the same image, then doing a copy operation. So you
actually have both anyway.
(<https://lists.cairographics.org/archives/cairo/2005-September/005355.html>)

Which I do not really understand - might this help solve the problem?

If not, it's really a pity that such a thing seems to be impossible 
with cairo as there are no alternative (image processing) libraries 
available for me in GJS. And looping through the pixels is not an 
option as it's too slow in GJS.

If anybody has another idea how this could be approached, I would be 
very grateful!

Regards,
Simon

On Sa, Dez 26, 2020 at 09:09, Uli Schlachter <psychon at znc.in> wrote:
> Hi,
> 
> Am 25.12.20 um 21:09 schrieb Simon Schneegans:
>>  But I am afraid your method does not yet accomplish my goal.
> [...]
>>  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:
> [...]
> 
> well... [/me investigates for a moment]... my copy_with_content()
> function does not actually do what it is supposed to do. Copying the
> original ARGB32 surface to an RGB24 surface behaves "as if" the ARGB32
> surface is drawn on a black background. Put differently, this just
> copies out the pre-multiplied pixel values, but we want/need the
> unmultiplied pixel values. Something needs to divide the color
> components by the alpha value for this approach to work.
> 
> A first idea would be to fill the color-components surface with white
> and then drawing the ARGB32 to_tint-surface with OVER. That makes the
> red gradient work (it ends up as all-white in the color-components
> surface), but of course it breaks the black gradient, because that one
> now also gets some white "mixed in" which is then tinted red.
> 
> Hm... division by the alpha value is needed. Looking through the list
> over compositing operators, OVER, DEST_OVER, XOR, SATURATE, and the
> blend modes contain division by the alpha value, but all of these
> multiply with the alpha value first. Thus, that cannot do what we 
> need here.
> 
> I think my approach cannot work correctly, sorry. :-(
> 
> Cheers,
> Uli
> --
> This can be a, a little complicated. Listen, my advice is... ask
> somebody else for advice, at least someone who's... got more 
> experience
> at...  giving advice.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20210105/8a6b6083/attachment.htm>


More information about the cairo mailing list