SVG-фильтры. Часть 1. Основные понятия и типы. Применение к изображениям для создания графических эффектов.
SVG-фильтры – это воистину мощный, но при этом очень редко используемый инструмент. A все потому, что многие до сих пор испытывают страх перед SVG в целом, а уж фильтрация и эффекты кажутся чем-то специфическим и трудным для изучения.
В этой статье я попытаюсь убедить Вас в обратном, расскажу о возможностях и типах SVG-фильтров и, в частности, о том, как применить их к изображениям на веб-страницах.
SVG-фильтры поддерживаются почти всеми современными браузерами, включая мобильные. Исключение составляют IE9 и Android native browser версии ниже 4.4.
Чтобы понять, что представляет из себя фильтр в SVG, давайте разберем простой пример. Для начала мы нарисуем круг:
Если Вы вообще не знакомы с SVG, то сейчас самое время познакомиться :)
- тег <circle> – это круг
- аттрибуты cx , cy – задают положение центра круга, fill – заливку, r – радиус.
То, что мы написали, будет выглядеть в браузере вот так:
Да, круто. Настоящий, большой и синий SVG-круг. А теперь давайте опишем простейший SVG-фильтр, задающий гаусовское размытие, и применим этот фильтр к нашей незамысловатой фигуре.
Сам фильтр определяется в секции <defs> с помощью тега <filter> . Ему необходимо задать id (уникальный в контексте всего документа). У нас это id="myFilter1" .
Внутри описываются типы применяемой фильтрации. В нашем примере это <feGaussianBlur> , где атрибут stdDeviation регулирует уровень размытия.
Забегая вперед, скажем, что спецификация определяет несколько типов фильтрации с большим количеством возможных атрибутов для настройки их параметров.
Далее к той части SVG, которая должна быть обработана фильтром, нужно добавить атрибут filter="url(#myFilter1)" с указанием id фильтра.
И вот что получится:
Да! Вот он – наш первый SVG-фильтр. Не так сложно, как казалось, не правда ли? Идем дальше. Давайте применим такой же фильтр к растровой картинке. Для этого поместим изображение красивой девушки в наушниках внутрь SVG:
И применим к изображению фильтр, описанный выше:
Получилась “разблюренная” девушка, как мы и ожидали. И это только начало. Продолжаем!
Комплексные SVG-фильтры. Применяем несколько эффектов последовательно.
Еще одним неотъемлемым достоинством SVG-фильтров является возможность сочетания нескольких типов фильтров. Т.е. результат, полученный после применения одного фильтра, может являться источником изображения для другого фильтра и т.д.
Чтобы было понятнее, давайте добавим еще один тип фильтрации для “разблюренной” девушки. Например, сделаем изображение черно-белым.
Графически эту схему фильтрации можно представить как:
Как Вы видите, для каждого типа фильтров можно указать атрибуты in и result . Если они не указаны, фильтры будут применяться последовательно в порядке их записи.
В качестве in для первого типа фильтра по умолчанию используется предопределенное значение SourceGraphic (в нашем случае оно является псевдонимом <image> )
Типы SVG-фильтров
Как мы уже говорили, существует несколько возможных типов фильтров. Давайте разберем каждый из них подробнее. Для простоты восприятия мы будем рассматривать только код, находящийся внутри тега filter . Все остальное остается таким же, как в предыдущих примерах.
feComponentTransfer
Фильтр <fecomponenttransfer> позволяет производить линейные, табличные, дискретные операции над каналами изображения, а также изменять гамму каждого канала.
Давайте рассмотрим примеры:
Здесь feFuncR , feFuncG , feFuncB , feFuncA – красный, зеленый, синий и канал прозрачности соответственно. type – тип преобразования, slope – множитель, intercept – добавляемое (отнимаемое) значение. T.е. <feFuncR type="linear" slope="5" intercept="-0.5" /> значит: red = red * 5 - 0.5
Вот так, например, можно сделать изображение полупрозрачным:
A вот так выделить только синий канал:
Или просто заполнить значения атрибутов случайными значениями и получить интересный эффект.
Вот демо всех примеров, приведенных выше.
Фильтр <fecomponenttransfer> поддерживает не только линейные преобразования. Тип преобразований задается атрибутом type и может принимать значения identity | table | discrete | linear | gamma . Давайте бегло взглянем, что из себя представляет каждый из типов.
fecomponenttransfer с type="table"В случае fecomponenttransfer с типом table функция преобразования для канала будет определена путем линейной интерполяции между значениями, указанными в атрибуте tablevalues . А вот так, например, можно добиться эффекта “негатива”, используя табличные значения:
fecomponenttransfer с type="discrete"Для типа discrete функция будет ступенчатой, в соответствии со значениями, указанными в атрибуте tablevalues . Вот несколько примеров:
Имеется также возможность задавать значения гаммы каждого канала при помощи типа фильтра type="gamma" и атрибутов amplitude , exponent и offset для каждого из каналов.
Например, <fefuncg type="gamma" amplitude="1.2" exponent="0.5" offset="0.2" /> значит: green = 1.2 * pow(green, 0.5) + 0.2
feColorMatrix
Фильтр позволяет умножить каждый пиксель исходного изображения в виде вектора, образованного каналами R , G , B , A и дополненного до размерности 5, на матрицу 5×5. В результате мы получим вектор, представляющий из себя каналы R' , G' , B' , A' каждого пикселя результирующего изображения.
Давайте сразу перейдем к примеру. Знакомый всем эффект “сепия” можно получить с помощью вот такой матрицы:
Матрица записывается в атрибут values фильтра <fecolormatrix> с типом matrix в виде значений, разделенных пробелом.
Последнюю строку не нужно указывать, т.к. она всегда равна | 0 0 0 0 1 | .
Для удобства чтения матрицу можно записать в таком виде:
Давайте посмотрим еще на несколько примеров с различными матрицами:
Частные случаи цветовых матриц – это поворот изображения по цветовому кругу, изменение цветности и т.п. Чтобы упростить жизнь разработчикам и не требовать умножения на матрицы для типовых операций в спецификации для фильтров , определены вспомогательные типы type=saturate , type=hueRotate , type=luminanceToAlpha . Давайте рассмотрим примеры их использования:
Обесцвечивание с type="saturate" , а также примеры, где цветность увеличена в 0, 0.5, 2, 5 раз, используя type="saturate" :
Поворот по цветовому кругу на 40, 120, 240, 320 градусов, используя type="hueRotate" :
Свертка feConvolveMatrix
В процессе свертки матрица коэффициентов «умножается» на значения каналов пикселей изображения. Будет намного проще представить это графически:
Действие над изображением (или фильтрование изображения) определяется матрицей свертки m . Матрица свертки определяет то, как конкретный пиксель зависит от соседних пикселей в процессе свертки. Пиксель у в результирующем изображении зависит от пикселей x0 … x8 исходя из следующей формулы:
y = x0×m0 + x1×m1 + . + x8×m8
Свертка используется в цифровой обработке изображений для различных целей. Это размытие, искусственное увеличение резкости и другие интересные эффекты.
Давайте посмотрим, как можно немного «подтянуть» резкость классического нечеткого #duckface изображения при помощи вот такого фильтра свертки с размерностью 3:
Оригинальное изображение (слева) и результат фильтрации (справа)
Далее представлены еще несколько примеров для различных фильтров свертки:
Композитные операции c feComposite
При помощи feComposite можно осуществлять арифметические и логические операции над слоями в svg.