#svg #svg-filters
#svg #svg-фильтры
Вопрос:
Когда я применяю фильтр размытия к изображению svg, он размывает края, поэтому они становятся немного прозрачными (см. Левый пример). Я хочу размыть его без такого артефакта (см. Правый пример). Я решил это с помощью взлома: просто скопировал одно и то же перевернутое изображение и разместил их на 4 стороны.
Есть ли лучший способ?
Обратите внимание, что я не могу просто увеличить изображение на 5-10%; размер должен быть таким же, как у исходного изображения.
Вот мой svg:
...
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="4"></feGaussianBlur>
</filter>
...
<g filter="url(#blur)">
<image xlink:href="cathedral.jpg"></image>
</g>
Ответ №1:
Это хороший способ создания четкой границы, который использует feComponentTransfer для увеличения непрозрачности краев до 1.0, но также требует, чтобы вы обрезали фильтр до размера фильтруемого элемента (используя атрибуты filter sizing в filter element) — если вы этого не сделаете, выпосмотрите, как переполнение нового непрозрачного размытия и черного фона выходит за пределы исходного изображения.
<filter id="blur" x="0%"
y="0%" width="100%" height="100%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
<feComponentTransfer>
<feFuncA type="discrete" tableValues="1 1"/>
</feComponentTransfer>
</filter>
...
<g filter="url(#blur)">
<image xlink:href="cathedral.jpg"></image>
</g>
Если у вас нет квадратного ввода (допустим, ваша фотография круглая), то вам нужно использовать feComposite «in», чтобы обрезать выходные данные до области ввода, а не использовать размеры фильтра. Но feComposites сейчас работают немного медленно и пока не могут использоваться как часть CSS-фильтра, поэтому приведенный выше метод предпочтительнее для квадратных входов.
Обратите внимание, что это не будет работать на изображениях с переменной непрозрачностью / альфа-каналом — все будет преобразовано в 100% непрозрачность.
Другой вариант — использовать feColorMatrix для выполнения того же самого, в некоторых браузерах, похоже, GPU ускоряет эту операцию, поэтому она может быть быстрее, чем feComponentTransfer
<filter id="blur" x="0%"
y="0%" width="100%" height="100%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
<feColorMatrix type="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0 1"/>
</filter>
...
<g filter="url(#blur)">
<image xlink:href="cathedral.jpg"></image>
</g>
Комментарии:
1. Похоже, это не работает. Смотрите здесь: jsbin.com/vugojiju/1/edit Я поместил то же изображение на обороте, чтобы проиллюстрировать проблему — прозрачные края размытого изображения.
2. Перед добавлением componentTransfer необходимо закрыть тег feGaussianBlur. В моем коде я использую самозакрывающийся <feGaussianBlur/> В вашей версии вы помещаете componenttransfer в набор тегов open и close feGaussian. Таким образом, он игнорирует передачу компонентов
3. Здесь опечатка: в первой строке x=»0% должно содержать закрывающую двойную кавычку. Кроме этого, потрясающий хак!