Порог альфа-канала SVG: резкая граница прозрачности
Используйте feFuncA для пороговой обработки альфа-канала SVG. Сравните discrete и table на известных пикселях PNG, сохраните отверстия и проверьте, почему остается непрозрачный белый.
На этой странице
- Сравните известные исходные пиксели перед выбором порога
- Примените преобразование к альфа-каналу
- Отличайте ступенчатую функцию от интерполируемой таблицы
- Отделяйте входную альфу от последующей непрозрачности
- Непрозрачный белый требует другой диагностики
- Подготовьте прозрачный растр перед восстановлением вектора
- FAQ
- Sources
Для порога альфа-канала 0.5 используйте feComponentTransfer с <feFuncA type="discrete" tableValues="0 1"/>. Входная альфа ниже 0.5 становится прозрачной, а значение от 0.5 и выше — непрозрачным. Не задавайте функции RGB, если хотите сохранить их тождественное преобразование.
Этот фильтр меняет отображаемую альфу, а не структуру изображения. Он не удалит непрозрачный белый фон: белые пиксели с альфой 1 проходят тот же порог, что и непрозрачные цветные пиксели. PNG, встроенный в SVG, также остается растровым изображением.
Сравните известные исходные пиксели перед выбором порога
Мы создали небольшой 8-битный PNG в формате RGBA с плавным изменением альфы, прозрачным квадратным отверстием, непрозрачным белым участком и шестью контрольными образцами. Каждый SVG в этом тесте содержит одни и те же байты PNG в одном элементе image. Версии без фильтра, с discrete и с интерполируемой таблицей отличаются только настройкой фильтра.
Шахматный фон ниже принадлежит окружающей странице и находится вне SVG. Он показывает прозрачность, а не имитирует часть альфа-канала изображения.

Наша страница загрузила реальные варианты SVG, нарисовала их на canvas в браузере и измерила значения внутри шести образцов. Выходные байты альфа-канала:
| Входной байт альфы PNG | Выход без фильтра | Discrete 0 1 | Table 0 1 |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 64 | 64 | 0 | 64 |
| 127 | 127 | 0 | 127 |
| 128 | 128 | 255 | 128 |
| 192 | 192 | 255 | 192 |
| 255 | 255 | 255 | 255 |
Нормализованные значения альфы равны этим байтам, деленным на 255. Поэтому 127/255 чуть меньше 0.5, а 128/255 чуть больше. Эти образцы находятся по разные стороны математического порога; 8-битный байт PNG не представляет ровно 0.5.
У исходного отверстия во всех версиях измерена альфа 0. У белого участка во всех версиях — 255. Это наблюдения для контролируемого тестового изображения, а не утверждение, что любое изображение после пороговой обработки сохранит все нужные детали.
Примените преобразование к альфа-каналу
Основной фильтр короткий:
<filter id="alpha" filterUnits="userSpaceOnUse"
x="0" y="0" width="320" height="240">
<feComponentTransfer in="SourceGraphic">
<feFuncA type="discrete" tableValues="0 1"/>
</feComponentTransfer>
</filter>Примените его к изображению через filter="url(#alpha)". Область фильтра в этом примере покрывает весь исходник и область просмотра размером 320 на 240. Выберите границы для своего изображения, а не копируйте эти размеры в другой файл.
Справочник MDN по feFuncA определяет этот элемент как функцию преобразования альфы внутри feComponentTransfer. Справочник по component-transfer описывает поканальное преобразование и вычисления для значений цвета без предварительного умножения на альфу.
Действующая спецификация Filter Effects задает тождественное преобразование для неуказанных функций каналов. В нашей разметке нет feFuncR, feFuncG и feFuncB: меняется только функция преобразования альфы. Это не означает, что видимые цвета на фоне будут выглядеть одинаково: изменение альфы меняет результат композиции.
Запустите полный тест с исходным PNG
Сохраните следующий самостоятельный SVG как alpha-test.svg и откройте в браузере. Его data URL содержит исходный контрольный PNG. Для сравнения с табличной версией замените только type="discrete" на type="table". Для сравнения с версией без фильтра удалите атрибут filter у изображения. Цветной или шахматный фон страницы поможет увидеть прозрачные области.
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="240" viewBox="0 0 320 240">
<defs><filter id="alpha" filterUnits="userSpaceOnUse"
x="0" y="0" width="320" height="240">
<feComponentTransfer in="SourceGraphic">
<feFuncA type="discrete" tableValues="0 1"/>
</feComponentTransfer>
</filter></defs>
<image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAYAAABxLb1rAAAJ6ElEQVR4nO3UVexsZxXG4eLBnRXcIVD3tKey66krENwhuEPQHjTFneAOwR2CM2hw6ql7m3rx4If3kgsCf+ierpk9z5c89+/6Ln4b1bphI4BV1D4AoEv7AIAu7QMAurQPAOjSPgCgS/sAgC7tAwC6tA8A6NI+AKBL+wCALu0DALq0DwDo0j4AoEv7AIAu7QMAurQPAOjSPgCgS/sAgC7tAwC6tA8A6NI+AKBL+wCALu0DALq0DwDo0j4AoEv7AIAu7QMAurQPAOjSPgCgS/sAgC7tAwC6tA8A6NI+AKBL+wCALu0DALq0DwDo0j4AoEv7AIAu7QMAurQPWKOrxdXjGnHNuFZcO64T143rxfXjBnHDuFHcOG4SN42bxc3jFnHLuFVU3DpuE7eN28Xt4w5xx7hT3DnuEneNu8Xd4x5xz7hX3Ds2jk1i09gsNo8tYsvYKraObWLb2C62jx1ix1gXO8XOsUvsGkPsFrvHHrFn7BV7xz6xb+wX+8cBcWAcFAfHIXFoHBaHxxFxn7hv3C/uHw+IB8aD4sHxkHhoPCweHo+IR8aj4tHxmHhsPC4eH0+IJ8aT4snxlHhqPC2eHs+IZ8az4tnxnHhuPC+eHy+IF8aL4shYHy+Ol8RL42Xx8nhFHBWvjFfFq+M18dp4Xbw+3hBvjDfFm+Mt8dZ4W7w93hHvjHfFu+M98d54X7w/PhAfjA/Fh+Mj8dH4WHw8PhGfjE/Fp+Mz8dn4XHw+vhBfjC/Fl+Mr8dX4Wnw9vhHfjG/Ft+M7MYvvxvfi+/GD+GH8KH4cP4mfxs/i5/GL+GX8Ko6OY+LYOC6OjxPixDgpTo5T4tQ4LU6PM+LMOCvOjnPi3Dgvzo8L4sK4KC6OS+LSuCwujyvi1/Gb+G38Ln4ff4g/xp/iz/GX+Gv8Lf4e/4gN1d8OASwBFEABFEABFMASQAEUQAEsARRAARTA7gFrJIACKIACKIAlgAIogAIogAJYAiiAAiiAJYACKIACKIACWAIogAIogCWAAiiAAiiAAlgCKIACKIAlgAIogAIogAJYAiiAAiiAJYACKIACuOAEUAAFUAAFsARQAAVQAAVQAEsABVAABbAEUAAFUAAFUABLAAVQAAWwBFAABVAABVAASwAnEcANTa8EsJ0ACqAACqAAlgAKoAAKoAAKYAmgAAqgAJYACqAACqAACmAJoAAKoACWAAqgAAqgAApgCaAACqAAlgAKoAAKoAAKYAmgAAqgAJYACqAACuCCE0ABFEABFMASQAEUQAEUQAEsARRAARTAEkABFEABFEABLAEUQAEUwBJAARRAARRAASwBFEABFMASQAEUQAEUQAEsARRAARTAuvIB7P6b/0YABVAABVAASwAFUAAFsARQAAVQAAVQAEsABVAAF54ACqAACqAAlgAKoAAKoAAK4BoJoAAKoAAKYAmgAAqgAJYACqAACqAACmAJoAAK4MITQAFc+QDG0XFMHBvHxfFxQpwYJ8XJcUqcGqfF6XFGnBlnxdlxTpwb58X5cUFcGBfFxXFJXBqXxeVxRQlgOwEUQAEUQAEsARRAARRAARTANRJAARRAARTAEkABFEABLAEUQAEUQAEUwBJAARTAhSeAAiiAAiiAJYACKIACKIACuEYCKIACKIACWAIogAIogCWAAiiAAiiAAlgCKIACuPAEUAAFUAAFsARQAAVQAAVQANdIAAVQAAVQAEsABVAABbAEUAAFUAAFUABLAAVQABeeAAqgAAqgAJYACqAACqAACuAaCaAACqAACmAJoAAKoACWAAqgAAqgAApgCaAACuDCE0ABFEABFMASQAEUQAEUQAFcIwEUQAEUQAEsARRAARTAEkABFEABFMBRArhxbBKbxmaxeWwRW8ZWsXVsE9vGdrF97BA7xrrYKXaOXWLXGGK32D32iD1jr9g79ol9Y7/YPw6IA+OgODgOiUPjsDg8jigBFEABFMASQAEUQAEUQAEsARRAARTAEkABFEABXAICKIACKIACWAIogAIogAIogCWAAiiAAlgCKIACKIACKIAlgAIogAJYAiiAAiiAAiiAJYACKIACWAIogAIogAIogCWAAiiAAlgCKIACKIALTgAFUAAFUABLAAVQAAVQAAWwBFAABVAASwAFUAAFUAAFsARQAAVQAEsABVAABVAABbAEUAAFUABLAAVQAAVQAAWwBFAABVAASwAFUAAFcMEJoAAKoAAKYAmgAAqgAAqgAJYACqAACmAJoAAKoAAKoACWAAqgAApgCaAACqAACqAAlgAKoAAKYAmgAAqgAAqgAJYACqAACmAJoAAKoAAuOAEUQAEUQAEsARRAARRAARTAEkABFEABLAEUQAEUQAEUwBJAARRAASwBFEABFMCJBJDFssgB7P4blkj7AJaSADIJ7QNYWosYwO4/Ycm0D2CpLVIAu/+CJdQ+gKUmgCy19gEsvUUIYPcfsKTaBzAJnQHsvp0l1j6ASRBAllL7ACajI4DdN7Pk2gcwKVdlALtvZQLaBzApAshSaR/A5FwVAey+kYloH8AkzTOA3bcxIe0DmCQBZCm0D2Cy5hHA7puYmPYBTNqYAey+hQlqH8CkCSALrX0AkzdGALtvYKLaB7ASrkwAu7czYe0DWAkCyEJqH8DK+H8C2L2ZiWsfwEr5XwLYvZUV0D6AlSKALJT2AayctQSweyMron0AK+k/BbB7GyukfQArSQBZCO0DWFn/LoDdm1gx7QNYaf8awO4trKD2Aaw0AaRV+wBW3voF2MCKah8A0KV9AECX9gEAXdoHAHRpHwDQpX0AQJf2AQBd2gcAdGkfANClfQBAl/YBC2xoMvYdRzYZ+471Tca+Y9Zk7Ds2NBn1jrE/ZUqGJmPfIYACOJvDHQI4cUOTse8QQAGczeEOAZy4ocnYdwigAM7mcIcATtzQZOw7BFAAZ3O4QwAnbmgy9h0CKICzOdwhgBM3NBn7DgEUwNkc7hDAiRuajH2HAArgbA53CODEDU3GvkMABXA2hzsEcOKGJmPfIYACOJvDHQI4cUOTse8QQAGczeEOAZy4ocnYdwigAM7mcIcATtzQZOw7BFAAZ3O4QwAnbmgy9h0CKICzOdwhgBM3NBn7DgEUwNkc7hDAiRuajH2HAArgbA53CODEDU3GvkMABXA2hzsEcOKGJmPfIYACOJvDHQI4cUOTse8QQAGczeEOAZy4ocnYdwigAM7mcIcATtzQZOw7BFAAZ3O4QwAnbmgy9h0CKICzOdwhgBM3NBn7DgEUwNkc7hDAiRuajH2HAArgbA53CODEDU3GvkMABXA2hzsEEGCZtQ8A6NI+AKBL+wCALu0DALq0DwDo0j4AoEv7AIAu7QMAurQPAOjSPgCgS/sAgC7tAwC6tA8A6NI+AKDLPwG8PYVZS9xMPAAAAABJRU5ErkJggg==" width="320" height="240" filter="url(#alpha)"/>
</svg>Полный пример сохраняет байты PNG. Фильтр не перекрашивает сохраненный исходный файл и не заменяет его контурами. Диагностика встроенного растра объясняет, почему расширение внешнего файла .svg не подтверждает наличие векторной геометрии.
Отличайте ступенчатую функцию от интерполируемой таблицы
Оба типа преобразования используют tableValues, но трактуют значения по-разному. Справочник по type перечисляет доступные функции преобразования, а справочник по tableValues описывает таблицу значений.
Для discrete каждое значение занимает равный входной интервал. При двух значениях 0 1 первый интервал — 0 ≤ A < 0.5, второй — 0.5 ≤ A ≤ 1. Выход скачком переключается между двумя значениями.
Для table значения задают концы участков линейной интерполяции. При 0 1 интерполяция возвращает каждую входную альфу без изменения. Это тождественное преобразование, поэтому измеренный столбец table совпадает со столбцом без фильтра.
Формулы интервалов в спецификации также объясняют следующие варианты:
| Настройка feFuncA | Преобразование альфы |
|---|---|
| discrete со значениями 0 1 | Жесткий порог 0.5 |
| discrete со значениями 0 0 0 1 | Жесткий порог 0.75 |
| table со значениями 0 1 | Тождественная интерполяция |
| table со значениями 0 0 1 1 | Плавный переход в середине вместо жесткого порога |
На снимке проверены варианты discrete и table с двумя значениями. Строки с четырьмя значениями описывают преобразования из спецификации; это не дополнительные измеренные варианты изображения. Выбирайте type осознанно: список только из нулей и единиц не обязательно дает бинарный порог.
Отделяйте входную альфу от последующей непрозрачности
Передавайте фильтру настоящую исходную альфу. В нашем примере она хранится в пикселях PNG. Для векторного теста задайте альфу заливки или fill-opacity до применения фильтра.
Модель композиции Filter Effects применяет фильтры перед opacity. Поэтому общая непрозрачность элемента или окружающей группы может уменьшить непрозрачность результата после фильтра. Если обработать исходник порогом, а затем скомпоновать результат с меньшей непрозрачностью, он снова может выглядеть полупрозрачным. В контролируемом тесте порога исключите эту последующую непрозрачность.
Жесткий порог также отбрасывает исходный полупрозрачный переход. Слабые пиксели исчезают, а оставшиеся полупрозрачные пиксели становятся полностью непрозрачными. Так можно потерять мягкое свечение или тонкую границу, которую вы хотели сохранить. Проверьте результат в конечном размере и на нескольких фонах. Бинарная выходная альфа не гарантирует, что отображаемая граница свободна от эффектов выборки и композиции.
Если полупрозрачность — часть дизайна, сохраните ее или используйте плавное преобразование вместо порога. Для намеренно монохромной маски видимости руководство по CSS-маскам SVG описывает другой способ отображения.
Непрозрачный белый требует другой диагностики
Белый участок сохраняется, потому что его альфа полностью непрозрачна. Операция отбирает пиксели по альфе, а не по тому, выглядят ли они белыми. Полностью непрозрачные пиксели фона не становятся прозрачными при этом преобразовании discrete со значениями 0 1.
Если в файле есть нежелательный белый фон, сначала определите, является ли он отдельной фигурой SVG или частью растрового изображения. Ненужную векторную фигуру фона удалите или измените напрямую. Если белый цвет записан в пикселях PNG, очистите растр перед восстановлением или используйте подходящий способ удаления фона. Руководство по прозрачному фону SVG объясняет эти случаи.
Прежде чем удалять фон по цвету, учтите действительно белые части объекта. Этот альфа-фильтр не может определить, какая белая область — фон, а какая принадлежит рисунку, и не восстановит информацию о цвете, потерянную при сведении исходника.
Подготовьте прозрачный растр перед восстановлением вектора
PerfectVector поможет, если готовый дизайн существует только в растре, а вам нужна геометрия SVG. Сначала подготовьте PNG с настоящей прозрачностью, затем конвертируйте PNG в SVG. Сравните предпросмотр на контрастном фоне, проверьте силуэт и отверстия, а в скачанном файле найдите ненужную геометрию фона.
Наш пример фильтра — эксперимент с отображением. Он не отправляет SVG с фильтром на векторизацию и не демонстрирует новый результат трассировки. Если нужно сохранить растровый вид после пороговой обработки, подготовьте и проверьте настоящую растровую копию для передачи в своем редакторе до восстановления вектора. Проверьте альфу этой копии, а не полагайтесь на предпросмотр в браузере.
Если есть векторный оригинал, используйте его напрямую. Сохраняйте полупрозрачность, когда она несет полезную информацию, и перерисуйте простой символ, если так его легче поддерживать. Обзор векторизации изображений отделяет восстановление растра от изменения отображения существующего SVG.
FAQ
Какой порог альфы использует discrete с tableValues 0 1? Входная альфа ниже 0.5 преобразуется в 0, а от 0.5 и выше — в 1. В проверенных 8-битных образцах PNG байт 127 становится прозрачным, а байт 128 — непрозрачным.
Почему tableValues 0 1 не меняет прозрачность? При type table эти значения задают линейную интерполяцию от 0 до 1, то есть тождественное преобразование. Для показанного здесь двухступенчатого преобразования используйте type discrete.
Удалит ли это белый цвет или превратит PNG в векторные контуры? Нет. Полностью непрозрачный белый проходит этот порог альфы. Наши варианты SVG по-прежнему содержат один и тот же PNG в одном элементе image и ни одного контура; очистка фона и восстановление вектора — отдельные задачи.
Sources
- W3C — Filter Effects Level 1 — Определяет тождественные значения по умолчанию, поканальное преобразование без предварительного умножения на альфу и формулы интервалов table/discrete.
- MDN — feComponentTransfer — Объясняет поканальное преобразование, выполняемое примитивом фильтра.
- MDN — feFuncA — Определяет функцию преобразования альфа-канала.
- MDN — type — Перечисляет типы функций преобразования компонентов и контекст атрибута.
- MDN — tableValues — Описывает значения таблицы для преобразований table и discrete.
Нужна векторная геометрия из растрового дизайна? Подготовьте и конвертируйте прозрачный PNG, затем проверьте силуэт и отверстия в предпросмотре и скачанный SVG на цветном фоне.
Ещё из блога

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

SVG в Matplotlib: график и логотип в виде контуров
Экспортируйте график Matplotlib в SVG, добавьте отдельные контуры логотипа через svgutils и проверьте итоговый файл на встроенные пиксели, размещение и изменения шрифтов.