[cairo] How to blur one of the r, g or b channels into the alpha channel?

A. Walton awalton at gmail.com
Mon Nov 12 19:06:30 PST 2007

I think the correct answer is convolution, a 3x3 gaussian convolution
filter would do exactly what he wants to do, but Cairo doesn't have
for Cairo-side convolution or very much in the way of filtering (yet).
Thusly, the way to do this is a bit, tedious, to say the least.

Isolating the part of the image you want to be blurred into its own
Cairo context (create an image surface the size you want, layout the
path, stroke, close the context and cairo_image_surface_get_data()),
and apply the filter (there are plenty of examples of how to do proper
convolution out there, I think there's even code buried in pixman
itself to do it; a really good reference to start with is located
here: http://www.echoview.com/WebHelp/Reference/Algorithms/Operators/Convolution_algorithms.htm
), then bring it back into Cairo
(cairo_image_surface_create_for_data()) and hack away.

Someday hopefully Cairo will get this internally, so you can skip the
export/import steps, but this is how I've been doing it and it works
pretty well. Hope that's helpful.

On Nov 12, 2007 6:01 PM, Travis Griggs <tgriggs at cincom.com> wrote:
> On Nov 12, 2007, at 12:37, Leon Woestenberg wrote:
> > Hello,
> >
> > I would like to blur one of the r, g or b channels into the alpha
> > channel.
> >
> > for each x,y: alpha(x,y) = blur3(x,y)
> > where blur3 is a 3x3 blurring filter
> >
> > What's the most efficient way to achieve this with cairo?
> >
> > My application is that I would like to "feather" a thick stroke.
> I did something like this a little while back and blogged about it
> with a big ol' wink cast.
> http://www.cincomsmalltalk.com/userblogs/travis/blogView?
> showComments=true&printTitle=Taking_Stock_In_Cairo&entry=3361198981
> I'm not aware of general blur function myself. I would love to hear
> if there is one. The way I achieved those "glowing" or "feathered"
> lines was to do a loop like this:
> for (int i = 17; i > 0; i-=2)
> {
>         line_width(cr, i);
>         source_rgba(cr, r, g, b, 1.0 / i);
>         stroke_preserve(cr);
> }
> pardon the psuedo code and probably misremembered function names (I'm
> going from memory and translating for the Smalltalk binding). The
> trick I found was setting alpha to the reciprocal of a the stroke width.
> --
> Travis Griggs
> Objologist
> "It's actually much easier to get around on ice than it is on dry land
> —if you use skates." - Paul Graham
> _______________________________________________
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo

More information about the cairo mailing list