[cairo] RGB channels are set to zero if alpha is 0.

Bram Stolk b.stolk at gmail.com
Sun Aug 27 17:03:10 UTC 2017


Thank you Benjamin,

This makes sense then, I understand it now.
Thanks for explaining.

I must say that PNG then makes for a very poor choice of writing to by
Cairo.
In Python at least, there seems to be no alternative to PNG.

['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'copy_page', 'create_similar', 'finish', 'flush', 'get_content',
'get_device_offset', 'get_fallback_resolution', 'get_font_options',
'mark_dirty', 'mark_dirty_rectangle', 'set_device_offset',
'set_fallback_resolution', 'show_page', 'write_to_png']

PNG is (by spec) never pre-multiplied.
Cairo works with pre-multiplied alpha.

So it is impossible to generate colour with zero alpha.

And because OpenGL's linear filtering will sample RGB channels of 100%
transparent texels, you will always get black for those, despite that they
are invisible due to zero alpha.
TIFF seems a better target for exports then, as it supports pre-multiplied
alpha.

  Bram




On Sun, Aug 27, 2017 at 3:41 AM, Benjamin Berg <benjamin at sipsolutions.net>
wrote:

> Hi,
>
> On Sat, 2017-08-26 at 17:55 -0700, Bram Stolk wrote:
> > Cairo is treating colours with alpha=zero incorrectly.
> > If alpha is zero, the red green and blue channels are zeroed by cairo,
> even
> > if they contain non zero r/g/b values.
>
> Please remember that pixman stores the data premultiplied. Because of
> this it should be the expected behaviour that the 1,1,1,0 colour from
> the left half of the image becomes 0,0,0,0 (even if you did set the
> operator to CAIRO_OPERATOR_SOURCE so that the paint is not a no-op).
>
> See also the documentation on CAIRO_FORMAT_ARGB32 in
>  https://cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t
>
> Regards,
> Benjamin
>
> > To demonstrate this bug, I wrote this python-cairo program that
> > creates an
> > image with two colours.
> > The left half of the image is set to 1,1,1,0.
> > The right half of the image is set to 1,1,1,1
> >
> > When cairo writes out the PNG, the left half of the image is
> > incorrect.
> > The pixels are 0,0,0,0 instead of 1,1,1,0.
> >
> > ---
> >
> > The test program:
> >
> > #! /usr/bin/env python
> > import cairo
> > from math import pi, sqrt
> >
> > width = 120
> > height = 120
> > filename = "out"
> >
> > surface = cairo.SVGSurface(filename + '.svg', width, height)
> > cr = cairo.Context(surface)
> >
> > cr.scale(width, height)
> > cr.set_line_width(0.01)
> >
> > cr.rectangle(0, 0, 0.5, 1)
> > cr.set_source_rgba(1, 1, 1, 0/255.0)
> > cr.fill()
> >
> > cr.set_source_rgba(1,1,1, 1/255.0)
> > cr.rectangle(0.5,0,1,1)
> > cr.fill()
> >
> > surface.write_to_png(filename + '.png')
> > cr.show_page()
> > surface.finish()
> >
> >
> >
>



-- 
Owner/Director of Game Studio Abraham Stolk Inc.
Vancouver BC, Canada
b.stolk at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20170827/483fba6f/attachment.html>


More information about the cairo mailing list