📜 ⬆️ ⬇️

Blurring Gaussian Images with SVG



In this topic, I would like to tell you how to add a Gaussian blur effect to images on a web page without using a flash. I planned to write the article a year ago, and, to my great surprise, no one has outstripped me, although the topic is quite simple and interesting both in terms of web design and in terms of client development. To create the effect, we will use the already popular technology SVG , which works in all the latest versions of browsers. For IE8-we will use CSS filters ( Blur in particular), which work only in Microsoft products. For a start, I suggest to get acquainted with the final version here (hover over any image). The script is presented in the form of jQuery plugin, but pull it out for use outside of jQuery is not difficult.

Obviously, the aim of the work is not only to blur the picture, but also to animate this blur.
')
From the simplest example, we can see that the intensity of the blur depends on the stdDeviation attribute in the feGaussian Blur tag.

< svg width ="100%" height ="100%" version ="1.1"
xmlns ="http://www.w3.org/2000/svg" >

< defs >
< filter id ="Gaussian_Blur" >
< feGaussianBlur in ="SourceGraphic" stdDeviation ="3" />
</ filter >
</ defs >

< ellipse cx ="200" cy ="150" rx ="70" ry ="40"
style ="fill:#ff0000;stroke:#000000;
stroke-width:2;filter:url(#Gaussian_Blur)"
/>

</ svg >


* This source code was highlighted with Source Code Highlighter .

(code taken from here ).
First of all, I tried to animate this attribute, but as it turned out, attribute values ​​can only be whole numbers, that is, the animation was “jerky”. To create the illusion of smooth animation, we will follow a very simple logic.



We make two layers: the first is a blurred image (SVG), the second is the original image (the usual html img), and we change the transparency to it, which is perfectly animated. In order to avoid problems with the positioning of elements relative to each other, a requirement was put: the original image should be contained in the container, for example, in the span tag, which will be further added and blurred image.

< span class ="blurImageContainer" >
< img class ="blurImage" src ="a.jpg" >
</ span >


* This source code was highlighted with Source Code Highlighter .

First of all, an object was created for convenient work with SVG:
var SVG = {

//
svgns: 'http://www.w3.org/2000/svg' ,
xlink: 'http://www.w3.org/1999/xlink' ,

// svg (name - , attrs - )
createElement: function (name, attrs){
var element = document .createElementNS(SVG.svgns, name);

if (attrs) {
SVG.setAttr(element, attrs);
}
return element;
},

// (element - SVG-)
setAttr: function (element, attrs) {
for ( var i in attrs) {
if (i === 'href' ) { // href xlink
element.setAttributeNS(SVG.xlink, i, attrs[i]);
} else { //
element.setAttribute(i, attrs[i]);
}
}
}
}


* This source code was highlighted with Source Code Highlighter .
This is all we need to correctly create several svg elements.

In order not to make a mistake of reusable use of the plugin to the same element, each time we will delete the element with blur, and for this we need to somehow identify it. Unfortunately, it was not possible to add a class to the svg element itself, but it turned out to assign it an ID:
var blurredId = Math.random(); //
...
$ this .children( '[id^="blurred"]' ).remove(); //
...

svg = SVG.createElement( 'svg' , {
...
id: 'blurred' +blurredId
});


* This source code was highlighted with Source Code Highlighter .
This will allow us to also avoid the conflict of ITDs of the blur filter to which the image refers.

As a result, we get the following code:
var svg, filterId, filter, gaussianBlur, image;
svg = SVG.createElement( 'svg' , { // SVG
xmlns: SVG.svgns,
version: '1.1' ,

//
width: imgWidth,
height: imgHeight,

id: 'blurred' +blurredId
});

filterId = 'blur' +blurredId; // ; image
filter = SVG.createElement( 'filter' , { //
id:filterId
});

gaussianBlur = SVG.createElement( 'feGaussianBlur' , { //
'in' : 'SourceGraphic' , //in — ; ,
stdDeviation: args.deviation // (int)
});

image = SVG.createElement( 'image' , { //,
x: 0,
y: 0,

//,
width: imgWidth,
height: imgHeight,
href: imgSrc,

style: 'filter:url(#' +filterId+ ')' //
});

filter.appendChild(gaussianBlur); //
svg.appendChild(filter); // SVG
svg.appendChild(image); // SVG
this .appendChild(svg); // SVG span ( this )


* This source code was highlighted with Source Code Highlighter .

which generates this SVG:
< svg xmlns ="http://www.w3.org/2000/svg" version ="1.1" width ="144" height ="144" id ="blurred0.9918661566916853" >
< filter id ="blur0.9918661566916853" >
< feGaussianBlur in ="SourceGraphic" stdDeviation ="2" ></ feGaussianBlur >
</ filter >
< image x ="0" y ="0" width ="144" height ="144" href ="a.jpg" style ="filter:url(#blur0.9918661566916853)" ></ image >
</ svg >


* This source code was highlighted with Source Code Highlighter .


Now let's get into the blur in earlier versions of IE. As mentioned above, the Blur filter will be used. The resulting blur is not quite according to Gauss, and it does not look very good, but it is not so important. We adhere to a similar principle: create a second image, put it under the original image, blur it.
$img.clone() //
.css({ //

// ; ,
filter: 'progid:DXImageTransform.Microsoft.Blur(pixelradius=' + args.deviation*2 + ')' ,

// ,
top: -args.deviation*2,
left: -args.deviation*2,

//- ;
width: imgWidth,
height: imgHeight,
})
.attr( 'id' , 'blurred' +blurredId)
.appendTo( this );


* This source code was highlighted with Source Code Highlighter .

We make the script as a jQuery plugin and use it as follows:
jQuery(window).load( function ($){ // , load ready
$( '.blurImageContainer .blurImage' ).css({opacity: 0}); //

$( '.blurImageContainer' ).gaussianBlur({
deviation: 3, //
imageClass: 'blurImage' //
});

$( '.blurImageContainer' ).hover( function (){
$( '.blurImage' , this ).animate({opacity: 1}, 500);
}, function (){
$( '.blurImage' , this ).animate({opacity: 0}, 500);
});
});


* This source code was highlighted with Source Code Highlighter .


Thanks for attention.
Please report any inaccuracies and shortcomings.

References:
finom.ho.ua/blur - an example
finom.ho.ua/blur/jquery.gaussian-blur.js - plugin code
www.w3.org/TR/SVG/filters.html - filter specification in SVG

PS In the course of work, an attempt was made to learn how to blur not only pictures, but also whole pieces of html. Despite the fact that it is not difficult to embed html in svg (that way), it was not possible to apply graphic filters. I would be glad if dear habra people help with the idea how to do it.

Source: https://habr.com/ru/post/123035/


All Articles