PerfectVector
Автор: Irene Kim

Выделение краёв SVG: предпросмотр feConvolveMatrix

Создайте предпросмотр краёв SVG с feConvolveMatrix, разберите артефакты альфа-канала и границ, сравните ядро резкости и проверьте наличие настоящих контуров в исходнике.

7 мин чтения
На этой странице

Выделение краёв SVG с помощью feConvolveMatrix меняет отрисованные пиксели вокруг границ цвета. Оно может создать предпросмотр краёв из PNG внутри SVG, но не создаёт редактируемые контуры. Не смешивайте эти задачи, если дальше нужно редактировать логотип, готовить линейный рисунок или создавать веб-графику.

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

Начните с контролируемого предпросмотра краёв

Справочник feConvolveMatrix описывает свёртку как вычисление с входным пикселем и его соседями. Это ядро 3 × 3 вычитает восемь соседей из восьмикратного центрального значения:

-1 -1 -1
-1  8 -1
-1 -1 -1

Сумма его коэффициентов равна нулю. В однородной области отклик нулевой; при изменении яркости он может быть положительным или отрицательным. При bias="0" отрицательные результаты обрезаются по нижнему пределу цвета. Поэтому предпросмотр не показывает обе стороны каждой границы одинаково.

Пример явно использует divisor="1". Справочник divisor описывает нормализацию этим значением и значение по умолчанию 1 для ядра с нулевой суммой. Также задано color-interpolation-filters="sRGB", чтобы пример использовал значения каналов sRGB вместо стандартной для примитива обработки linearRGB.

Сохраните этот полный самодостаточный файл как edge-preview.svg и откройте в браузере. Встроенный PNG — оригинальный ромб 48 × 48 в оттенках серого на непрозрачной белой бумаге. Середина белая, а не прозрачная.

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
  <defs>
    <filter id="effect" filterUnits="userSpaceOnUse" x="0" y="0" width="48" height="48" color-interpolation-filters="sRGB">
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="-1 -1 -1 -1 8 -1 -1 -1 -1" divisor="1" bias="0" targetX="1" targetY="1" edgeMode="duplicate" preserveAlpha="true"/>
    </filter>
  </defs>
  <image width="48" height="48" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABOklEQVR4nNWZQQ7EIAwDU7+seTlPo1ppTyvRhcQGxYeeGuNpEZT06r13KyxYccGKC1ZcsOKCFRfUA7h7XQD/hldCQGX8G1oFAYXpKKwCAmzDfyHZEGCazYZjQoBltBqKBQGGSTSMEyDSANkQnqxPAbCmgSd8wgDs1cSDflAP1lqT+IYBIuGVENj15FUQUJiOwiogwDSbCcmGAMNkNRwTApniaKjV+/0lB06Ej9T5IA9Ord+rdW2Q53UKKSFYbxiZ4mgo5vQEw0R1ImsT405vZAwIxcKAacckhGpVw/SdAfNIX6gtLslX9P+AokXSAvtJ+EAT3bzYfjgxKNMHJwdn1FPaKju+heSNLeXX6LbWouI8sL25yzyRHWuvM87Ex39wZLoSS+pi3fct9b8+FyssWHHBigtWXDgdIKsHsU1cbk4FPAgAAAAASUVORK5CYII=" filter="url(#effect)"/>
</svg>

Определение фильтра действует только потому, что изображение ссылается на него через filter="url(#effect)". Справочник фильтров SVG объясняет, что само определение не рисуется. Явная область покрывает этот исходник 48 × 48; другой графике нужна собственная проверка области.

Что изменилось в браузерном тесте

Мы проверили шесть оригинальных образцов в Chrome при 48 и 192 CSS-пикселях. Пять файлов содержат одно встроенное PNG-изображение и не содержат контуров. Шестой — независимо нарисованный вручную векторный аналог. Это геометрический контроль, а не результат применения фильтра или трассировки PNG.

ОбразецНаблюдаемый видСчитанные значения в однородном образце
Исходный PNG в SVGСерый ромб с белой серединой и бумагойСплошной серый: RGBA 64, 64, 64, 255
Ядро краёв, альфа-канал сохранёнЧёрное поле с откликом краёв; очертание слабое при большем показеЦентр и угол: RGBA 0, 0, 0, 255
Ядро краёв, альфа-канал тоже фильтруетсяПрозрачный результат в этом примереЦентр, угол и сплошной образец: RGBA 0, 0, 0, 0
Контроль повышения резкостиРомб с заливкой сохранён, граничные пиксели измененыСплошной серый остался RGBA 64, 64, 64, 255
Ядро краёв, граница с нулевыми значениямиПоявилась яркая внешняя рамкаУгол: RGBA 255, 255, 255, 255
Контрольный контур, нарисованный вручнуюЧистый геометрический ромб и внутреннее отверстие на белой бумагеОдин элемент path, нет элементов image

Образцы RGBA получены считыванием Canvas 48 × 48 для каждого отрисованного SVG. Показанные образцы отдельно проверялись в обоих размерах. Это наблюдения для данного исходника и браузера, а не гарантия совместимости или читаемости. Увеличение растрового предпросмотра не восстановило более чистый контур.

Пиксельный отклик и редактируемая геометрия
Концептуальная иллюстрация сравнивает ромб пиксельного отклика краёв в оттенках серого с независимо нарисованным коралловым ромбическим кольцом и узлами редактирования
Иллюстрация: пиксельный предпросмотр краёв и редактируемый контур имеют разное представление. Это не снимок браузера и не результат преобразования.

Исправьте исчезновение результата, не стирая бумагу

По умолчанию preserveAlpha равно false. При этой настройке ядро обрабатывает и альфа-канал. У нашего непрозрачного входа альфа везде равна 1, поэтому ядро краёв с нулевой суммой обнуляет однородный альфа-канал вместе с однородным цветом. В проверенном примере результат исчез.

Установка preserveAlpha="true" сохраняет исходный альфа-канал при обработке цвета. Это различие описано в справочнике preserveAlpha. В этом тесте настройка восстанавливает непрозрачный предпросмотр краёв. Она также оставляет непрозрачными бумагу и белую середину, хотя их отфильтрованный цвет становится чёрным. Сохранение альфа-канала не удаляет фон и не находит отверстия в логотипе.

Если предпросмотр преимущественно чёрный, сначала сравните известную однородную область с известной границей. Чёрный может быть корректным нулевым откликом. Чтобы проверить изменения яркости с учётом знака вокруг среднего тона, попробуйте bias="0.5"; справочник bias объясняет смещение, добавляемое после деления. Это меняет диапазон отображения, а не геометрию SVG.

Проверяйте границы отдельно от рисунка

Для первого сравнения оставьте edgeMode="duplicate". Он продолжает значения краевых пикселей, когда соседние образцы выходят за входное изображение. none использует образцы RGBA с нулевыми значениями; wrap берёт образцы с противоположного края. Это разные правила из справочника edgeMode.

На нашей непрозрачной белой карточке замена только duplicate на none создала яркую рамку по внешнему краю карточки. Эта граница относится к прямоугольнику изображения, а не к ромбу. Сравните файл без фильтра, прежде чем считать рамку контуром графики.

Спецификация Filter Effects определяет целевую точку ядра и поведение выборки. Здесь targetX="1" и targetY="1" центрируют ядро 3 × 3. В этом стартовом примере kernelUnitLength не задан. Не предполагайте, что соседний образец всегда отстоит на одну пользовательскую единицу SVG при любом размере показа; проверяйте итоговую отрисовку.

Используйте резкость как контроль, а не восстановление размытия

Чтобы сохранить графику с заливкой, подчёркивая локальные изменения, замените только kernelMatrix на:

0 -1  0
-1 5 -1
0 -1  0

Сумма равна 1. Однородное значение канала c возвращает 5c - 4c = c при divisor 1 и bias 0. В нашем примере сплошной серый образец остался равным 64, а граничные пиксели изменились. Для этого сравнения сохраните preserveAlpha="true" и edgeMode="duplicate".

Повышение резкости может подчёркивать шум и ореолы вместе с полезными границами. Оно не восстанавливает исходные детали, потерянные до попадания изображения в фильтр. Если увеличенный предпросмотр выглядит плохо, вернитесь к исходному изображению, а не считайте более сильное ядро заменой разрешению исходника.

Проверьте файл, прежде чем называть его векторной трассировкой

Опубликованный стартовый пример содержит <image>, чей href начинается с data:image/png. Справочник элемента image описывает растровые и SVG-ресурсы, которые он может показывать. Здесь тип медиа определяет встроенный растр; фильтр краёв оставляет этот элемент на месте.

Для сравнения независимо созданный мастер использует этот составной контур поверх белого прямоугольника:

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
  <rect width="48" height="48" fill="white"/>
  <path d="M24 6 L42 24 L24 42 L6 24 Z M24 17 L31 24 L24 31 L17 24 Z"
        fill="#404040" fill-rule="evenodd"/>
</svg>

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

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

PerfectVector подходит, если исходная графика — плоский PNG или JPG, а вам нужны редактируемые исходные фигуры. Преобразуйте оригинальное изображение в SVG, проверьте контур и внутреннее отверстие и сохраните чистый результат как мастер. Успешный предпросмотр краёв не заменяет эту проверку. Руководство по векторизации объясняет отличие восстановления контуров от применения эффекта изображения.

Частые вопросы

Создаёт ли выделение краёв SVG feConvolveMatrix векторные контуры? Нет. Оно вычисляет отрисованный пиксельный эффект. Встроенный PNG в этом примере остаётся элементом image; редактируемым контурам нужна отдельно нарисованная или трассированная геометрия.

Почему фильтр краёв заставляет графику исчезнуть? Проверьте preserveAlpha. Стандартное false фильтрует и альфа-канал. В этом непрозрачном примере ядро с нулевой суммой сделало проверенный результат прозрачным. Сохранение альфа-канала восстановило непрозрачный предпросмотр.

Удаляет ли preserveAlpha белый фон? Нет. Он сохраняет исходный альфа-канал. Непрозрачный белый фон остаётся непрозрачным, даже когда отфильтрованный цвет становится чёрным. Удаление фона и восстановление контуров — отдельные задачи.

Почему фильтр краёв рисует рамку вокруг изображения? Проверьте edgeMode и входной прямоугольник. Нулевые значения образцов за нашей непрозрачной белой карточкой создали яркую внешнюю границу. Обработка краёв duplicate позволила избежать этой границы в данном примере.

Источники

  1. MDN: feConvolveMatrix — свёртка по соседним пикселям и стандартная обработка цвета.
  2. MDN: divisor — нормализация и значение по умолчанию при нулевой сумме.
  3. MDN: filter — определение и применение эффекта фильтра.
  4. MDN: preserveAlpha — обработка только цвета и обработка с альфа-каналом.
  5. MDN: bias — сдвиг отклика после деления.
  6. MDN: edgeMode — обработка границ duplicate, wrap и нулевыми значениями.
  7. W3C: Filter Effects, feConvolveMatrix — правила целевой точки и выборки.
  8. MDN: image — содержимое растровых и SVG-изображений по ссылке.

Ещё из блога

PerfectVector

Начните с более чистого SVG,
который проще редактировать

Без банковской карты