miércoles, 3 de marzo de 2010

Problem with SVG feConvolveMatrix filter with kernel which sum is zero

Here I will document an issue that I had working with SVG feConvolveMatrix primitive filter that was a really pain for me but has a simple solution.

My problem was using feConvolveMatrix filter primitive to apply operations like blur, sharp, edge detection, etc to images. Everything works OK, except for kernel matrix which elements sum equals 0.

For example, the following filters works as spected:


<filter id="vstripe">
<feConvolveMatrix order="3"
kernelMatrix="
2 -1 2
-1 2 -1
2 -1 2"
/>
</filter>


but the following filter (with a kernel which elements sum equals 0) won't work ( will show an empty rectangle):


<filter id="vstripe">
<feConvolveMatrix order="3"
kernelMatrix="
-1 -1 -1
-1 8 -1
-1 -1 -1"
/>
</filter>


This problem manifest only for svg elements and in all svg user agents (mozilla, webkit, opera, inskape, etc). This problem is very frustrating because, there are a lot of convolution filters that use kernels which element sum must be 0 (specially edge detector filters).

The problem was because of the alpha channel of images. In most images, the alpha channel has a constant value for all pixels in a region and so, a convolution using these kernels will give 0 (totally transparent) and that is the reason for the empty rectangle.

The solution is setting the parameter preserveAlpha="true" so the alpha channel is not processed in the convolution:


<filter id="vstripe">
<feConvolveMatrix order="3" preserveAlpha="true"
kernelMatrix="
-1 -1 -1
-1 8 -1
-1 -1 -1"
/>
</filter>


I hope this article can help those poor souls that, like me, are stagnant with this problem.

No hay comentarios: