SVG feMorphology: обводка без новых контуров
Создайте обводку SVG из SourceAlpha с помощью feMorphology. Сравните расширение, сжатие, отверстия и разные радиусы, сохранив исходную геометрию контуров.
На этой странице
Чтобы обвести весь силуэт многоцветного SVG, расширьте его SourceAlpha, вычтите исходный альфа-канал из увеличенного результата, окрасьте оставшееся кольцо и наложите сверху исходное изображение. Фильтр меняет отображаемый вид, сохраняя исходные данные контуров.
Используйте operator="erode", если нужно уменьшить альфа-силуэт. Ни одна из операций не создает редактируемый контур со смещением. Отверстия, узкие зазоры и острые углы нужно проверить визуально: морфология использует прямоугольную окрестность, а не круговое смещение обводки.
Начните с силуэта, а не с цветовых каналов
Спецификация W3C Filter Effects определяет расширение как покомпонентный максимум в прямоугольной окрестности, а сжатие — как минимум. При использовании SourceAlpha входными данными служит альфа-канал изображения. Так можно получить силуэт, не расширяя отдельно бирюзовый и коралловый цветовые каналы.
В этом примере фильтр применяется ко всему изображению из двух контуров. Его прозрачное квадратное отверстие — часть альфа-силуэта. Коралловая вставка уже находится внутри непрозрачной бирюзовой области, поэтому не создает отдельной внешней границы.
Мы создали SVG вручную и открыли пять самостоятельных вариантов в браузере. В каждом файле сохранены те же два исходных определения контуров. Ниже показано фактическое отображение этих файлов, без трассированного изображения или сгенерированного предпросмотра эффекта.

При радиусе 10 обводка растет за пределы видимого силуэта и внутрь отверстия. При 22 золотой цвет заполняет квадратное отверстие этого образца. Вариант 18 4 расширяется сильнее по горизонтали, чем по вертикали. Сжатие уменьшает непрозрачную внешнюю область и увеличивает прозрачное отверстие; нижний выступ тоже меняется.
Эти наблюдения относятся именно к этому изображению и этим настройкам. Они не задают общее правило безопасного радиуса для других логотипов или значков.
Постройте внешнее альфа-кольцо
Сохраните этот полный пример как outline.svg и откройте его в браузере. Это именно тот SVG с радиусом 10, который использовался для снимка:
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="220" viewBox="0 0 300 220">
<defs>
<g id="artwork">
<path fill="#173b40" fill-rule="evenodd"
d="M50 60H250V170H170L150 195L130 170H50Z M105 90H145V130H105Z"/>
<path fill="#f28567" d="M175 90H220V140H175Z"/>
</g>
<filter id="outline" filterUnits="userSpaceOnUse"
primitiveUnits="userSpaceOnUse" x="0" y="0" width="300" height="220">
<feMorphology in="SourceAlpha" operator="dilate" radius="10" result="grown"/>
<feComposite in="grown" in2="SourceAlpha" operator="out" result="ring"/>
<feFlood flood-color="#e4b84c" result="paint"/>
<feComposite in="paint" in2="ring" operator="in" result="coloredRing"/>
<feMerge>
<feMergeNode in="coloredRing"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<use href="#artwork" filter="url(#outline)"/>
</svg>Фильтр выполняет четыре рабочих шага:
feMorphologyрасширяетSourceAlpha, получаяgrown.feCompositeоставляет частьgrownвне исходного альфа-канала, получаяring.feFloodзадает золотой цвет; еще одна операция композиции ограничивает этот цвет кольцом.feMergeпомещает исходныйSourceGraphicнад окрашенным кольцом.
При вычитании важен порядок входов. Раздел спецификации о композиции определяет in как источник, а in2 как назначение. Здесь in="grown", in2="SourceAlpha" и operator="out" удаляют исходную непрозрачную область из расширенного альфа-канала. Перестановка этих входов не дает такого внешнего кольца.
Слово снаружи означает снаружи непрозрачной альфа-области, в том числе в пространстве внутри прозрачного отверстия. Если обводка не должна затрагивать внутренние отверстия, этот фильтр не различает их автоматически. Нужен отдельный силуэт или другое построение, определяющее нужную внешнюю границу.
Исходные цвета остаются видимыми, потому что неизмененный SourceGraphic добавляется последним. Это отличается от обычной обводки контура. Обводки по центру, с отсечением внутри или с маской снаружи описаны в статье о выравнивании обводки SVG; порядок отрисовки объясняет более простой случай наложения обводки и заливки.
Сожмите альфа-канал и сохраните оставшиеся цвета
Замените фильтр обводки следующим определением и измените последний элемент use на filter="url(#erode)":
<filter id="erode" filterUnits="userSpaceOnUse"
primitiveUnits="userSpaceOnUse" x="0" y="0" width="300" height="220">
<feMorphology in="SourceAlpha" operator="erode" radius="10" result="shrunken"/>
<feComposite in="SourceGraphic" in2="shrunken" operator="in"/>
</filter>Эта операция композиции сохраняет исходное изображение только там, где остался сжатый альфа-канал. Она не накладывает поверх полное исходное изображение, поскольку это скрыло бы задуманное утончение. В этом образце внешняя бирюзовая область уменьшается, а коралловая область внутри нее сохраняется.
В рабочих примерах задавайте оператор явно. Справка по operator различает erode и dilate у feMorphology и in и out у feComposite. Одинаково названный атрибут выполняет разные задачи у этих двух элементов. Оператор морфологии по умолчанию — erode, поэтому, пропустив его, легко получить эффект, противоположный задуманному расширению.
Разделяйте единицы радиуса и область фильтра
Справка по radius допускает одно или два числа. Одно применяется к обеим осям; при двух первое задает радиус по x, а второе — по y. Для двух дополнительных вариантов обводки измените в полном примере только radius="10" на radius="22" или radius="18 4".
Это радиусы в системе координат, выбранной через primitiveUnits, а не обещание границы фиксированной толщины в CSS-пикселях при любом размере отображения. Мы явно используем primitiveUnits="userSpaceOnUse" с viewBox 0 0 300 220. При изменении отображаемого размера SVG эффект масштабируется вместе с изображением.
Два атрибута с похожими названиями управляют разными вещами:
| Атрибут | Чем управляет | Настройка в примере |
|---|---|---|
| primitiveUnits | Значения длины внутри примитивов, включая радиус морфологии | userSpaceOnUse |
| filterUnits | Значения x, y, width и height области фильтра | userSpaceOnUse |
| Корневой viewBox | Прямоугольник пользовательских координат, отображаемый в области просмотра SVG | 0 0 300 220 |
Справка MDN по primitiveUnits описывает систему координат примитивов. Справка по filterUnits отдельно описывает внешнюю область. По умолчанию filterUnits равен objectBoundingBox, а primitiveUnits — userSpaceOnUse. Явное задание обоих упрощает проверку примера.
Исходное изображение занимает диапазон x от 50 до 250 и y от 60 до 195. Наибольший проверенный радиус, одинаковый по осям, — 22; область фильтра и область просмотра размером 300 на 220 оставляют место для этого результата. При изменении изображения или радиуса заново проверьте обе границы. Спецификация описывает область фильтра как жесткое отсечение: больший радиус не позволяет рисовать за ее пределами. Руководство по отсечению фильтра и области просмотра SVG показывает эти два отдельных ограничения.
Если фильтр кажется неактивным, проверьте также radius. По умолчанию он равен 0, а справка указывает, что отрицательное или нулевое значение отключает эффект примитива. В примерах выше для обеих осей явно заданы положительные значения.
Проверьте отверстия и углы перед передачей файла
Прямоугольная окрестность морфологии придает ей вид, отличный от обычной скругленной обводки. Одинаковые радиусы по x и y не превращают эту окрестность в круг. Ступенчатый нижний выступ на сравнении — удобное место для проверки этой разницы.
| Результат | Что проверить перед использованием |
|---|---|
| Увеличенная внешняя обводка | Отверстия и соседние формы могут визуально соединиться |
| Сжатый силуэт | Тонкие детали могут исчезнуть, а отверстия — увеличиться |
| Разные радиусы по осям | Расширение по горизонтали и вертикали намеренно различается |
| Правильный предпросмотр в браузере | Принимающий редактор или инструмент экспорта все равно требует отдельной проверки |
| Обводка нужна как редактируемая геометрия | Результат действующего фильтра не является новым контуром в исходном файле |
Мы проверили, что все пять файлов по-прежнему содержат два исходных контура с одинаковыми атрибутами d. Определения фильтров различаются; исходная геометрия — нет. Проверьте реальные объекты SVG, если в целевой программе нужны контуры, которые можно редактировать, смещать или отправлять в производство. Для этого примените геометрическую операцию редактора и затем проверьте получившиеся контуры. Одно лишь изменение или удаление фильтра их не создает.
Сохраните исходный файл без фильтра и отдельную копию для передачи. Откройте передаваемый файл там, где он будет использоваться, и сравните углы, внутренние отверстия, цвета и границы. Этот пример в браузере не подтверждает поддержку в конкретном дизайнерском приложении, инструменте экспорта или режущей машине.
Подготовьте исходник перед добавлением эффекта
PerfectVector может помочь, если исходное изображение существует только в PNG или JPG. Подготовьте пробный SVG, затем проверьте восстановленный силуэт, небольшие отверстия и границы цветов перед применением фильтра. Морфологическая обводка усилит проблемы этого силуэта, а не исправит за вас задуманную геометрию.
Если векторный оригинал доступен, используйте его напрямую. Для простого символа ручная перерисовка может дать больше контроля. Трассировка сведенного изображения с уже встроенной обводкой не восстанавливает исходные настройки фильтра и не устанавливает, какая часть была фигурой без фильтра. Обзор векторизации изображений объясняет это ограничение восстановления.
Частые вопросы
Создает ли feMorphology редактируемый контур обводки? Нет. Он меняет отображаемый результат фильтра. В этом примере сохраняются те же два исходных контура, поэтому для целевой программы, которой нужен отдельный контур, требуется геометрическая операция и проверка импорта.
Почему золотая обводка заполняет отверстие в моем SVG? Кольцо растет за пределы непрозрачного альфа-канала, в том числе внутрь прозрачных отверстий. В этом образце радиус 22 заполняет квадратное отверстие. Для другого изображения нужно отдельно проверить зазоры и радиус.
Зачем использовать SourceAlpha вместо SourceGraphic? SourceAlpha позволяет фильтру работать с силуэтом, не расширяя каждый исходный цветовой канал. В примере это альфа-кольцо окрашивается отдельно, а SourceGraphic накладывается последним, чтобы показать исходные цвета.
Источники
- W3C — Filter Effects Level 1 — Определяет прямоугольную окрестность морфологии, входы композиции и отсечение по области фильтра.
- MDN — radius — Определяет синтаксис радиуса с одним и двумя значениями, единицы и значения, отключающие эффект.
- MDN — operator — Различает операции морфологии и композиции.
- MDN — primitiveUnits — Устанавливает систему координат радиуса морфологии.
- MDN — filterUnits — Устанавливает систему координат внешней области фильтра.
Если исходник доступен только в растре, подготовьте векторное изображение с PerfectVector, проверьте силуэт без фильтра и отверстия, затем добавьте обводку и сравните итоговый файл в той программе, где его будут просматривать.
Ещё из блога

Обводки SVG исчезают после экспорта: найдите причину
Обводки SVG могут исчезать из-за окраски, масштаба, обрезки или неподдерживаемых эффектов. Сначала проверьте контур, затем примените минимальное надёжное исправление.

SVG-изображения Graphviz: переносимая графика узлов
Добавьте SVG-графику в узел Graphviz, проверьте ссылку на изображение и сравните полный комплект ресурсов, перенесенную диаграмму и автономную копию для передачи.