Blur Effect with cairo
Wondered how to apply convolution filters, like for instance gaussian blur in cairo. Doesn't seem to be possible yet. Well, unless you remember that cairo uses pixman as backend for its image surface. Result of my hacks below:

The code is in the blur_image_surface() function of blur-effect.c. Now the question is how to make a nice cairo API for this code, and how to hardware accelerate this. At least XRender seems to define API for convolution filters.
Update: Get full code via git clone http://taschenorakel.de/git/playground
Hi Mathias, i had tried to compile it, but when i run an error is occurred.
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_height: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_height: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_height: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_width: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_width: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_width: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_height: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_width: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_height: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_pixels: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_rowstride: assertion `GDK_IS_PIXBUF (pixbuf)' failed
(blur-effect:8711): GdkPixbuf-CRITICAL **: gdk_pixbuf_get_n_channels: assertion `GDK_IS_PIXBUF (pixbuf)' failed
why????
I'm sorry but i'm a newbie!!!! :D
Thanks...
I've compiled and everything is OK.
Thanks of your great code!
@ciccio
Have you put the two images to the folder?
@ciccio: Like TualatriX said: You probably forgot the two images. The code has just demo quality, added some simple error handling.
@TualatriX: Thanks, added some few comments for convenience.
Hey Mathias!
While XRender does allow you to do gaussian-blurs (among other convolution-based filtering), it's dead slow. Mainly because it's not hw-accelerated yet. Will it ever be? For example: updates of one "frame" make my GeForce 8800 almost come to a halt. See http://macslow.thepimp.net/?p=85 for my example XRender-based blur-toy.
I've also written some generic gaussian-blur code that operates on cairo-image surfaces and does not interface with pixman. Just giving your pixman-based example a spin for comparison. I'll get back to you later.
Best regards ...
MacSlow
thanks Mathias great job!!!
Now works fine ;)
...i don't why the file changed it's names :D
what is the name of that theme?
Really nice code! Example comes buggy when you resize the window to be really big though (not maximize just resize it to like 1500x1000 or so).
@Martin: Thanks for reporting that issue. Bug fixed.
Hi ,Mathias,
I got an error there.
CRITICAL **: blur_image_surface: assertion `cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE' failed
g_return_val_if_fail
(cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE,
NULL);
Is there something wrong?
Using "==" instead of "!=" is working fine for me.
Thanks.
Since gaussian blur is independent for x and y you can carry out the blurring as two 1D convolutions instead of one 2D convolution, which should be much faster. The larger the kernel is, the faster the speed up.
You only need a box blur for this. Gaussian is overkill.