SVG-фильтры – размытие по Гауссу, тени и освещение

SVG-фильтры создают визуальные эффекты, такие как размытие, отбрасываемые тени, освещение, изменение насыщенности, поворот оттенка и корректировка каналов, прямо в SVG-разметке. В этом руководстве объясняется, как фильтры определяются в <defs>, как примитивы фильтров работают вместе и как применять фильтр к фигурам, тексту или изображениям.

Краткий ответ: определите SVG-элемент <filter> внутри <defs>, добавьте один или несколько примитивов фильтра, например <feGaussianBlur>, <feOffset>, <feBlend>, <feSpecularLighting> или <feColorMatrix>, и примените фильтр к целевому элементу с помощью filter="url(#filter-id)".

1<svg width="220" height="140" xmlns="http://www.w3.org/2000/svg">
2  <defs>
3    <filter id="soft-blur">
4      <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
5    </filter>
6  </defs>
7  <circle cx="110" cy="70" r="45" fill="#20b2aa" filter="url(#soft-blur)" />
8</svg>

В этой статье вы узнаете, как:

Что такое SVG-фильтр?

SVG-фильтры добавляют визуальные эффекты к растровой или векторной графике до вывода окончательного результата. Фильтр может размыть элемент, создать тень, изменить цветовые каналы, добавить освещение, исказить пиксели или объединить несколько промежуточных результатов в один эффект. Поскольку эффект остается частью SVG-разметки, он масштабируется вместе с векторной графикой и остается доступным для редактирования.

Фильтр определяется элементом <filter>, размещенным внутри блока <defs>. Сам <filter> не отображается; его дочерние элементы – примитивы фильтра – выполняют фактическую обработку. Элемент <filter> задает систему координат и область, в которой работают все примитивы фильтра. Он поддерживает следующие ключевые атрибуты:

SVG-фильтры и примитивы фильтров

SVG-фильтры строятся путем объединения нескольких примитивов фильтра.

В таблице ниже приведен обзор часто используемых элементов SVG-фильтра, их назначения и ключевых атрибутов. Большинство строк описывает примитивы фильтра; элементы источника света, такие как <fePointLight>, используются внутри примитивов освещения.

КатегорияЭлемент фильтраНазначениеКлючевые атрибуты
Размытие по Гауссу<feGaussianBlur>Размывает входное изображение с использованием гауссовой функцииin, stdDeviation, result
Отбрасываемая тень<feOffset>Смещает альфа-канал, создавая основу тениin, dx, dy, result
Отбрасываемая тень<feGaussianBlur>Смягчает смещенную теньin, stdDeviation, result
Отбрасываемая тень<feBlend>Смешивает тень с исходной графикойin, in2, mode
Световые эффекты<feGaussianBlur>Сглаживает альфа-канал, используемый как карта рельефаin, stdDeviation, result
Световые эффекты<feSpecularLighting>Создает зеркальное, блестящее освещение с помощью источника светаin, surfaceScale, specularConstant, specularExponent, lighting-color, result
Световые эффекты<feDiffuseLighting>Создает диффузное освещение с помощью источника светаin, surfaceScale, diffuseConstant, lighting-color, result
Световые эффекты<fePointLight>Определяет точечный источник света для примитивов освещенияx, y, z
Световые эффекты<feComposite>Объединяет освещение с исходной графикойin, in2, operator, k1, k2, k3, k4, result
Световые эффекты<feMerge>Объединяет несколько результатов фильтра в один вывод
Цветовые фильтры<feColorMatrix>Применяет матричные преобразования цветаin, type, values, result
Цветовые фильтры<feComponentTransfer>Применяет функции переноса цвета по отдельным каналамin, result

Каждому фильтру требуется входное изображение или исходная графика для обработки. Без входных данных фильтру нечего отображать. Атрибуты in и result важны, потому что позволяют одному примитиву передавать свой вывод следующему примитиву в цепочке.

Как создавать SVG-фильтры

  1. Добавьте блок <defs> для хранения определений фильтров, которые не должны отображаться сами по себе.
  2. Создайте элемент <filter> и задайте ему стабильный id.
  3. Добавьте один или несколько примитивов фильтра, например <feGaussianBlur>, <feOffset>, <feBlend> или <feColorMatrix>.
  4. Используйте in и result, если последующий примитив должен получить вывод предыдущего.
  5. Расширьте x, y, width и height, если размытие, тень или освещение выходят за пределы исходной фигуры.
  6. Примените фильтр к целевой фигуре, тексту, группе или изображению с помощью filter="url(#id)".

Размытие по Гауссу

Размытие по Гауссу смягчает изображение или фигуру, распределяя соседние пиксели по гауссовой функции. В SVG его часто используют для теней, свечения, мягкого фокуса, уменьшения детализации и направленного размытия.

Примитив <feGaussianBlur> создает размытие. Атрибут stdDeviation управляет радиусом размытия. Одно значение размывает одинаково в обоих направлениях. Два значения создают направленное размытие: первое значение применяется вдоль оси x, второе – вдоль оси y.

В примере ниже сравниваются разные значения stdDeviation в одном SVG-файле ( gaussian-blur.svg):

 1<svg height="400" width="600" xmlns="http://www.w3.org/2000/svg">
 2    <defs>
 3        <filter id="f1" x="-20%" y="-20%" width="140%" height="140%">
 4            <feGaussianBlur in="SourceGraphic" stdDeviation="10" />
 5        </filter>
 6        <filter id="f2" x="-20%" y="-20%" width="140%" height="140%">
 7            <feGaussianBlur in="SourceGraphic" stdDeviation="10, 0" />
 8        </filter>
 9        <filter id="f3" x="-20%" y="-20%" width="140%" height="140%">
10            <feGaussianBlur in="SourceGraphic" stdDeviation="0,10" />
11        </filter>
12    </defs>
13    <g stroke="none" fill="#20B2AA">
14        <ellipse cx="60" cy="80" rx="55" ry="35" />
15        <ellipse cx="200" cy="80" rx="55" ry="35" filter="url(#f1)" />
16        <ellipse cx="340" cy="80" rx="55" ry="35" filter="url(#f2)" />
17        <ellipse cx="500" cy="80" rx="55" ry="35" filter="url(#f3)" />
18    </g>
19</svg>

Четыре эллипса показывают эффект размытия по Гауссу с разными значениями stdDeviation

Размытие обычно расширяет видимый результат за пределы исходной фигуры. Если область фильтра слишком мала, размытые края обрезаются. В примере область фильтра расширена отрицательными значениями x и y, чтобы смягченные края оставались видимыми.

Вы можете создать эффект размытия по Гауссу на C# с помощью API Aspose.SVG for .NET. Чтобы узнать больше о пространстве имен Aspose.Svg.Filters и посмотреть подробные примеры C# с использованием класса SVGFEGaussianBlurElement для применения эффекта размытия по Гауссу к SVG-элементам и растровым изображениям, обратитесь к статье Размытие по Гауссу.

Эффект отбрасываемой тени

Отбрасываемая тень отделяет фигуру или текст от фона. В SVG тень обычно строится из альфа-канала источника, смещения, размытия и шага смешивания или объединения.

Примитив фильтра <feOffset> используется для смещения слоя в SVG. Помимо атрибутов in и result, этот примитив принимает два основных атрибута – dx и dy, которые задают расстояние смещения слоя по осям x и y соответственно. Примитив фильтра <feBlend> смешивает два входных слоя; его атрибут mode определяет режим смешивания.

Следующий SVG создает мягкую отбрасываемую тень для эллипса ( drop-shadow-effect.svg):

 1<svg height="200" width="200" xmlns="http://www.w3.org/2000/svg">
 2    <defs>
 3        <filter id="shadow" x="-20%" y="-20%" width="150%" height="150%">
 4            <feOffset result="offset" in="SourceAlpha" dx="10" dy="10" />
 5            <feGaussianBlur result="blur" in="offset" stdDeviation="10" />
 6            <feBlend in="SourceGraphic" in2="blur" mode="normal" />
 7        </filter>
 8    </defs>
 9    <ellipse cx="95" cy="90" rx="75" ry="55" fill="#20B2AA" filter="url(#shadow)" />
10</svg>

Эффект отбрасываемой тени у эллипса

Пошаговое объяснение

  1. <feOffset> берет in="SourceAlpha", сдвигает альфа-маску на 10 пикселей вправо и на 10 пикселей вниз и сохраняет промежуточный результат как "offset". Использование SourceAlpha создает тень по контуру фигуры, а не по цвету заливки.
  2. <feGaussianBlur> берет in="offset", применяет размытие со значением 10 и сохраняет результат во временном буфере с именем "blur".
  3. <feBlend> берет in="SourceGraphic" и in2="blur", затем выводит исходный эллипс вместе с размытой смещенной тенью.

Пошаговое создание эффекта отбрасываемой тени у эллипса

Вы можете создать эффект отбрасываемой тени на C# с помощью API Aspose.SVG for .NET. В статье Эффект отбрасываемой тени подробнее рассматривается пространство имен Aspose.Svg.Filters и показаны C#-примеры применения тени к SVG-фигурам и тексту.

Световые эффекты SVG

Световые эффекты SVG создаются внутри одного <filter> с помощью примитивов освещения, таких как <feDiffuseLighting> и <feSpecularLighting>, а также элементов источника света, например <fePointLight>. Примитивы освещения используют альфа-канал источника как карту поверхности и рассчитывают, как свет должен выглядеть на этой поверхности.

Элемент <fePointLight> определяет точечный источник света и используется как дочерний элемент <feDiffuseLighting> или <feSpecularLighting>. Его атрибуты x, y и z задают положение источника света. Диффузное освещение создает матовую освещенную поверхность, а зеркальное освещение – более блестящий блик.

Рассмотрим пример светового эффекта ( light-effect.svg):

 1<svg height="300" width="300" xmlns="http://www.w3.org/2000/svg">
 2    <defs>
 3        <filter id = "F1">
 4            <feGaussianBlur in = "SourceAlpha" stdDeviation = "4" result = "blur" />
 5            <feSpecularLighting result = "light" in = "blur" specularExponent = "25" lighting-color = "#bbbbbb">
 6                <fePointLight x = "80" y = "60" z = "200" />
 7            </feSpecularLighting>
 8            <feComposite in = "SourceGraphic" in2 = "light" operator = "arithmetic" k1 ="0" k2 ="1" k3 ="1" k4 ="0" />
 9        </filter>
10    </defs>
11    <g  fill = "INDIANRED" filter = "url(#F1)">
12        <circle cx="100" cy="100" r="60" />
13        <circle cx="100" cy="230" r="60" />
14        <circle cx="230" cy="100" r="60" />
15        <circle cx="230" cy="230" r="60" />
16    </g>
17</svg>

Результат применения эффекта освещения к четырем красным кругам

Пошаговое объяснение

В этом примере световой эффект создается цепочкой SVG-элементов внутри одного <filter>: три элемента являются примитивами фильтра, а <fePointLight> задает источник света:

  1. <feGaussianBlur> принимает вход SourceAlpha, то есть альфа-канал исходного изображения. Результат сохраняется во временном буфере с именем "blur".
  2. Освещение создается с помощью <feSpecularLighting> и его дочернего элемента <fePointLight>. <feSpecularLighting> использует буфер "blur" как карту высот поверхности и сохраняет блик в "light".
  3. <feComposite> берет in="SourceGraphic" и in2="light", затем объединяет их с помощью арифметической операции композитинга. Для каждого пикселя арифметический оператор вычисляет: result = k1·in1·in2 + k2·in1 + k3·in2 + k4.

Код ниже демонстрирует еще один пример цепочки примитивов фильтра и источника света внутри одного <filter> ( button.svg):

 1<svg height="200" width="200" xmlns="http://www.w3.org/2000/svg">
 2    <defs>
 3        <filter id="myF" x="-20%" y="-20%" width="160%" height="160%">
 4            <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
 5            <feOffset in="blur" dx="5" dy="5" result="offsetBlur" />
 6            <feSpecularLighting in="offsetBlur" surfaceScale="8" specularConstant="0.7" specularExponent="2" lighting-color="#bbbbbb" result="specOut">
 7                <fePointLight x="-100" y="-100" z="100" />
 8            </feSpecularLighting>
 9            <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut" />
10            <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="1.5" k2="0.5" k3="1" k4="0" result="litPaint" />
11            <feMerge>
12                <feMergeNode in="offsetBlur" />
13                <feMergeNode in="litPaint" />
14            </feMerge>
15        </filter>
16    </defs>
17    <ellipse cx="85" cy="70" rx="65" ry="45" fill="#20B2AA" filter="url(#myF)" />
18    <g fill="#696969" font-size="25" font-family="arial">
19        <text x="55" y="80">PUSH</text>
20    </g>
21</svg>

Синяя кнопка с текстом “PUSH”, созданная с помощью цепочки примитивов освещения

В статье Световые эффекты SVG показано, как объединять примитивы фильтра и источники света для создания SVG-освещения на C# с помощью API Aspose.SVG for .NET.

Цветовые фильтры

В SVG можно создавать множество цветовых эффектов, которые поддерживаются почти всеми современными браузерами. Когда речь идет об обработке цвета, <feColorMatrix> часто является лучшим вариантом. Это примитив фильтра, который использует матрицу для изменения значений цвета каждого канала RGBA. <feComponentTransfer> – еще один мощный примитив SVG-фильтра. Он дает контроль над отдельными каналами RGBA изображения, позволяя создавать SVG-эффекты в стиле Photoshop; например, его можно использовать для постеризации изображений.

Этот раздел посвящен двум практичным цветовым примитивам: <feColorMatrix> для матричных преобразований и <feComponentTransfer> для поканального редактирования.

Пример насыщенности feColorMatrix

Примитив фильтра <feColorMatrix> применяет матричное преобразование к каналам RGBA каждого пикселя входного изображения. В результате создается новый набор значений цвета и альфа-канала. Атрибут type может быть:

Рассмотрим примеры использования операции saturate ( saturation.svg):

1<svg width="640" height="480" viewBox="0 0 640 480" xmlns="http://www.w3.org/2000/svg">
2    <defs>
3        <filter id="myFilter">
4            <feColorMatrix in="SourceGraphic" type="saturate" values="0"></feColorMatrix>
5        </filter>
6    </defs>
7    <image filter="url(#myFilter)" href="https://docs.aspose.com/svg/images/drawing/park.jpg" width="100%" height="100%" />
8</svg>

Серия изображений с разными значениями насыщенности

Пример поворота оттенка feColorMatrix

Одна из операций цветовой матрицы – поворот оттенка по цветовому кругу. Следующий пример показывает использование операции hueRotate.

1<svg width="640" height="480" viewBox="0 0 640 480" xmlns="http://www.w3.org/2000/svg">
2    <defs>
3        <filter id="hueR">
4            <feColorMatrix in="SourceGraphic" type="hueRotate" values="40"></feColorMatrix>
5        </filter>
6    </defs>
7    <image filter="url(#hueR)" href="https://docs.aspose.com/svg/images/drawing/park.jpg" width="100%" height="100%" />
8</svg>

На рисунке ниже показана серия изображений, иллюстрирующих разные значения hueRotate.

Серия изображений с различными значениями hueRotate

Пример управления каналами feComponentTransfer

Примитив <feComponentTransfer> выполняет поканальные операции со значениями RGBA. Он полезен для настройки яркости, изменения контраста, балансировки каналов и создания эффектов постеризации цвета.

Пример ниже изменяет красный, зеленый и синий каналы независимо:

 1<svg width="640" height="480" viewBox="0 0 640 480" xmlns="http://www.w3.org/2000/svg">
 2    <defs>
 3        <filter id="RGBA">
 4            <feComponentTransfer>
 5                <feFuncR type="linear" slope="2.0" />
 6                <feFuncG type="linear" slope="1.7" />
 7                <feFuncB type="linear" slope="0.1" />
 8                <feFuncA type="identity" />
 9            </feComponentTransfer>
10        </filter>
11    </defs>
12    <image filter="url(#RGBA)" href="https://docs.aspose.com/svg/images/drawing/park.jpg" width="100%" height="100%" />
13</svg>

Фотография, обработанная пользовательским переносом компонентов RGBA

Элемент <feComponentTransfer> изменяет цветовые каналы через дочерние элементы передаточной функции: <feFuncR>, <feFuncG>, <feFuncB> и <feFuncA>. Каждый дочерний элемент управляет красным, зеленым, синим или альфа-каналом. Атрибут type выбирает функцию преобразования для соответствующего канала. SVG поддерживает пять типов функций: identity, table, discrete, linear и gamma.

В статье Цветовые фильтры показано, как создавать цветовые фильтры на C# с примитивами feColorMatrix и feComponentTransfer.

Типичные ошибки и исправления

ПроблемаПричинаРешение
Результат фильтра обрезаетсяОбласть фильтра (x, y, width, height) слишком малаРасширьте область фильтра, используя отрицательные значения x и y, а также увеличенные width и height
Отбрасываемая тень не виднаТень использует SourceGraphic вместо SourceAlpha или смешивается некорректноИспользуйте SourceAlpha как вход для <feOffset> и смешайте его с исходной графикой
Эффект освещения выглядит плоским или незаметнымАльфа-канал не подготовлен как карта рельефа или значения освещения слишком малыРазмойте SourceAlpha перед освещением и настройте параметры освещения
Цвета меняются неожиданноПрименена некорректная цветовая матрица или значения переносаПрименяйте цветовые фильтры напрямую к SourceGraphic и проверяйте значения шаг за шагом

Быстрые рецепты

Создать простое размытие по Гауссу

1<filter id="blur">
2    <feGaussianBlur in="SourceGraphic" stdDeviation="6" />
3</filter>

Применить направленное размытие по горизонтали или вертикали

1<filter id="directionalBlur">
2    <feGaussianBlur in="SourceGraphic" stdDeviation="8 0" />
3</filter>

Добавить мягкую отбрасываемую тень

1<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
2    <feOffset in="SourceAlpha" dx="6" dy="6" result="offset" />
3    <feGaussianBlur in="offset" stdDeviation="6" result="blur" />
4    <feBlend in="SourceGraphic" in2="blur" mode="normal" />
5</filter>

Ограничить размытую тень исходной формой

1<filter id="clippedShadow">
2    <feOffset in="SourceAlpha" dx="4" dy="4" result="offset" />
3    <feGaussianBlur in="offset" stdDeviation="4" result="blur" />
4    <feComposite in="blur" in2="SourceAlpha" operator="in" result="shadow" />
5    <feComposite in="SourceGraphic" in2="shadow" operator="over" />
6</filter>

Преобразовать изображение в оттенки серого

1<filter id="grayscale">
2    <feColorMatrix type="saturate" values="0" />
3</filter>

Настроить яркость и контраст

1<filter id="brightnessContrast">
2    <feComponentTransfer>
3        <feFuncR type="linear" slope="1.2" intercept="0.1" />
4        <feFuncG type="linear" slope="1.2" intercept="0.1" />
5        <feFuncB type="linear" slope="1.2" intercept="0.1" />
6    </feComponentTransfer>
7</filter>

Объединить несколько результатов фильтра

1<filter id="combined">
2    <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur" />
3    <feOffset in="blur" dx="4" dy="4" result="offset" />
4    <feMerge>
5        <feMergeNode in="offset" />
6        <feMergeNode in="SourceGraphic" />
7    </feMerge>
8</filter>

FAQ – SVG-фильтры

Как применить SVG-фильтр к элементу?

Определите фильтр в <defs> и примените его с помощью filter="url(#filter-id)" к фигуре, текстовому элементу, группе или изображению. id в определении фильтра должен совпадать со значением, используемым в атрибуте filter.

Почему мое SVG-размытие или тень обрезается?

Эффекты размытия и тени часто выходят за пределы исходного объекта. Расширьте область фильтра с помощью x, y, width и height, чтобы сгенерированным пикселям хватало места для отображения.

В чем разница между feColorMatrix и feComponentTransfer?

Используйте <feColorMatrix>, когда цветовые значения должна преобразовать одна матричная операция, например оттенки серого, насыщенность или поворот оттенка. Используйте <feComponentTransfer>, когда нужен раздельный контроль красного, зеленого, синего или альфа-канала.

Можно ли создавать SVG-фильтры с Aspose.SVG for .NET?

Да. В статье SVG-фильтры в C# показано, как программно создавать SVG-фильтры с помощью Aspose.SVG for .NET.

Связанные ресурсы