[cairo] Premultiplied transparency causes streaks in images

Paril paril at alteredsoftworks.com
Fri Nov 12 01:17:46 PST 2010

No, test.png was created by Cairo, and then pixel data (which is
premultiplied, as I am aware of) was copied to a GDI+ Bitmap and saved. I
did this to get an idea of what Cairo was doing internally.

What I did with this output was tested this out in GIMP to see what effect
this "brush" had; this output produced the same streaking in GIMP as it did
in my test program, which leads me to believe that Cairo is using these
premultiplied values during painting, which it should not be doing, as the
white transparency is turning into black.

I don't have the time at the moment to put together a test app, all I have
is my C# painting program, but all it is doing is using some of the basic
stuff from Mono.Cairo to draw images onto the form. Here's what I am doing,
in order:

1) Brush is selected from list; an empty Cairo ImageSurface is made to hold
the brush image.
2) All of the pixels in the bitmap (acquired from DevIL) are iterated
3) The color values are multiplied by the color selected in the color
picker. The alpha from color picker is discarded, and only used later on.
4) Since I am setting pixel data directly, I am multiplying the r, g and b
values by the alpha value.
5) Data is set to the ARGB integer from said color.
6) Drawing, by clicking on the form, is done by getting this brush image,
creating a SurfacePattern on the brush, setting its filter to Gaussian,
creating a Matrix (for the Scale operation) and scaling it, setting the
pattern's scale, creating context, translating to x/y of mouse, setting
source to pattern, PaintWithAlpha on alpha set in the color picker.

I can wrap up my current C# work and put it online if that will work - I
don't know if you can look at that at all, otherwise I'll put together a C
application for it.


On Fri, Nov 12, 2010 at 4:07 AM, Andrea Canciani <ranma42 at gmail.com> wrote:

> On Fri, Nov 12, 2010 at 7:24 AM, Paril <paril at alteredsoftworks.com> wrote:
> > Hi there.
> >
> > I'm writing a small app kind of like Paint, and using images as brushes;
> > these images are transparent PNGs with white as the brush color, and the
> > color is multiplied in the code to the color selected in a color picker,
> > with transparency being applied in PaintWithAlpha.
> >
> > This problem is generic to cairo and not the API I'm using, hence why I'm
> > posting here.
> Could you provide a small C program reproducing the problem?
> (The one using circle.png to generate test.png would be good)
> >
> > Because cairo pre-multiplies the colors, it is obvious to expect that any
> > transparency would be multiplied into black; this makes sense to me,
> > however, with my understanding of pre-multiplied alpha, it is
> un-multiplied
> > by the rendering API so that it renders alpha properly. This appears not
> to
> > be the case, as all of my images render with an ugly black outline which
> > destroys alpha blending and creates "streaks" across the program.
> >
> > Here is the image being used as a brush, and the image that is outputted
> by
> > Cairo after loading:
> > http://alteredsoftworks.com/cairo/circle.png
> > http://alteredsoftworks.com/cairo/test.png
> >
> > Does anyone have any experience with this sort of issue that they can
> tell
> > me what the problem is or how to combat it?
> If you are accessing the image data directly, you have to handle it as
> premultiplied.
> In particular from the images you provided, my guess is that test.png was
> not generated using cairo png API (which unpremultiplies the data before
> storing it in the png file).
> Andrea
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20101112/52a5596c/attachment.html>

More information about the cairo mailing list