PerfectVector
Автор: Irene Kim9 мин чтения

Почему отверстия в SVG заполняются и как их вернуть

Отверстия в SVG могут заполняться, если вырез перестаёт быть частью составного контура, меняется правило заливки или импортёр теряет связь. Найдите причину и восстановите её.

На этой странице

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

Сначала откройте SVG в браузере. Если отверстие залито уже там, исправьте файл. Если в браузере всё правильно, а другая программа заполняет отверстие, вероятная причина — этап импорта.

Быстрая диагностика
  • Поместите рисунок на контрастный фон. Белый объект — не прозрачное отверстие.
  • Проверьте нужный объект на панели Layers или Objects. Внешний и внутренний контуры обычно должны принадлежать одному составному контуру.
  • Если файл использует fill-rule="nonzero", направление контура имеет значение. При evenodd вложенные контуры поочерёдно образуют залитые и незалитые области.
  • Если ошибка возникает только в одной программе, упростите копию или заново выполните вычитание в ней.
  • Если просвет уже закрыт в исходном растре, очистите исходник перед повторной трассировкой.

Сначала выясните, где исчезло отверстие

Прежде чем менять геометрию, сравните два средства отображения:

  1. Сохраните копию SVG.
  2. Откройте её напрямую в Chrome, Safari, Firefox или другом браузере.
  3. Поместите рисунок на светлый и тёмный фон.
  4. Откройте тот же файл в целевой программе.
  5. Сравните конкретное отверстие, а не только общий силуэт.
Что вы видитеВероятная причинаСледующий шаг
Отверстие залито и в браузере, и в редактореОшибка структуры SVG или поведения заливкиПроверьте составные контуры, правило заливки и направление контуров
На тёмном фоне отверстие белоеБелая фигура перекрывает рисунокВычтите её или создайте настоящее прозрачное отверстие
В браузере всё правильно, в целевой программе — нетИмпортёр изменил или проигнорировал связь составного контураУпростите копию или вычтите внутренний профиль после импорта
Отверстие пропало сразу после Break Apart или ReleaseВнутренний контур стал обычным залитым контуромОтмените действие или снова объедините нужные контуры
Отверстие уже было закрыто после трассировки растраЗазор в исходнике был слишком мал или сглаживание соединило его краяОчистите исходник и повторите трассировку либо вырежьте отверстие вручную

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

Белая фигура — не отверстие

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

Для проверки добавьте временный тёмный прямоугольник за рисунком. Если предполагаемое отверстие осталось белым, выделите этот внутренний объект. Его можно сохранить как намеренный белый элемент дизайна, но не ожидайте, что режущий плоттер, инструмент гравировки, наложение в браузере или 3D-импортёр воспримет его как пустое пространство.

Для прозрачного отверстия используйте составной контур или вычтите внутреннюю фигуру из внешней. Маска тоже может создавать прозрачность, но многие производственные программы надёжнее обрабатывают простую геометрию контуров. Для программного процесса попробуйте вырезание и объединение импортированных контуров через Paper.js, затем заново откройте экспортированный SVG и проверьте отверстие.

Для рисунка гобо даже правильно сделанное прозрачное отверстие требует отдельного решения о материале. Сравнение стального и стеклянного гобо рассматривает одну и ту же букву O в стальной конструкции с перемычками и в рисунке на стекле и объясняет, почему инверсия светлых и тёмных областей проекции меняет то, что должно оставаться соединённым.

Составные контуры сохраняют связь с отверстием

Буква O, кольцо и логотип с вырезанным центром часто используют один элемент path с несколькими замкнутыми подконтурами. Внешний контур задаёт силуэт, а вложенный подконтур — просвет или вырез. Модель контуров SVG допускает несколько подконтуров внутри одного контура.

Поэтому Ungroup, Break Apart и Release Compound Path не взаимозаменяемы. Разъединение составного контура может превратить внутренний контур в обычный залитый объект. Геометрия остаётся, но её связь с внешним контуром теряется.

Восстановите её на копии:

  1. Выделите внешнюю границу и только те контуры, которые должны быть отверстиями.
  2. Используйте Make Compound Path, Combine или аналогичную команду.
  3. Примените одну заливку к полученному объекту.
  4. Проверьте правило заливки.
  5. Заново откройте сохранённый SVG в браузере и целевой программе.

Текущая документация Adobe по составным контурам использует ту же модель: составляющие контуры определяют залитые и прозрачные области через правило заливки.

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

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

Сравните nonzero и evenodd

В SVG два правила заливки. Спецификация отрисовки SVG 2 задаёт nonzero как начальное значение и определяет evenodd как другой вариант.

  • nonzero использует пересечения контуров с учётом направления. Внутренний контур с неправильным направлением может добавлять заливку, а не отменять её.
  • evenodd считает пересечения. Точка, окружённая дважды, оказывается снаружи, поэтому простой вложенный контур становится отверстием независимо от направления.

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

<path
  fill="#2563eb"
  fill-rule="evenodd"
  d="M10 10H90V90H10Z M30 30H70V70H30Z"
/>

Изменение правила полезно, когда оно соответствует рисунку, но это не универсальный способ исправления. Оба контура всё равно должны рассматриваться как подконтуры одной фигуры. Установка fill-rule="evenodd" на двух независимых объектах не заставляет один прорезать другой.

Если вы сохраняете nonzero, измените направление только внутреннего контура, если редактор предоставляет такую команду. Illustrator позволяет выбирать оба правила заливки и управлять направлением частей составного контура. Сохраните копию перед изменением направления: самопересечения и несколько вложенных просветов могут дать иной результат, чем простое кольцо.

Когда SVG правильный, а импортёр ошибается

Некоторые инструменты резки, CAD, 3D и анимации поддерживают лишь практическое подмножество SVG. Браузер может правильно отображать составной контур, а целевая программа — импортировать каждый контур как сплошной объект.

Исправляйте в таком порядке:

  1. Сохраните упрощённую копию из исходного редактора.
  2. Преобразуйте редактируемый текст в контуры в этой копии, если проблема в импорте текста.
  3. Замените маски, обрезку и эффекты оформления простой геометрией контуров только там, где это необходимо.
  4. Сохраняйте каждое нужное отверстие вместе с внешним контуром в одном составном контуре.
  5. Осознанно проверьте evenodd и nonzero, а не переключайте их снова и снова.
  6. Если импортёр всё ещё заполняет отверстие, импортируйте обе границы и вычтите внутренний профиль в целевой программе.

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

Когда трассировка закрыла отверстие

Трассировщик может закрыть просвет в маленькой букве или соединить узкий зазор, если растровый исходник слишком мал, размыт или имеет низкий контраст. Это проблема геометрии, а не правила заливки: внутренняя граница вообще не попала в SVG.

Вернитесь к растровому исходнику и:

  • увеличьте его или снимите заново, не добавляя размытия;
  • увеличьте разделение вокруг важного отверстия;
  • удалите шум сжатия около зазора;
  • уменьшите сглаживание или объединение цветов, если инструмент позволяет ими управлять;
  • сравните новую трассировку в окончательном размере вывода.

Здесь может помочь PerfectVector. Используйте процесс преобразования изображения в вектор, если у вас есть исходный растр и нужна новая SVG-трассировка. Перед скачиванием проверьте каждый просвет и каждое пустое пространство. Если SVG был правильным, пока редактор не разъединил составные контуры, исправьте сам SVG; повторная трассировка не восстановит потерянную историю редактирования.

Тот же подход, начинающийся с исходника, полезен для надписей. Руководство по векторизации ручного леттеринга показывает, как сохранить маленькие просветы, не лишая весь рисунок характера.

Безопасная итоговая проверка

Перед отправкой исправленного SVG:

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

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

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

Почему отверстия заполнились после команды Break Apart? Break Apart отделила внутренние контуры от внешнего составного контура. Бывшие отверстия стали обычными залитыми объектами. Отмените команду или снова объедините каждый внешний контур с нужными внутренними, затем проверьте правило заливки.

Стоит ли использовать fill-rule="evenodd" для отверстий в SVG? evenodd часто удобно для вложенных контуров, поскольку результат не зависит от их направления. Оно всё равно работает в пределах одной фигуры и не вычитает отдельный объект. Сохраняйте nonzero, если исходник и целевая программа сохраняют нужные направления контуров.

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

Можно ли сделать отверстие, положив сверху белую фигуру? Это лишь имитация отверстия на белом фоне. Белый объект остаётся залитым, поэтому может печататься, вырезаться или импортироваться как ещё одна сплошная фигура. Если фон должен просвечивать, используйте составной контур, вычитание или другую структуру прозрачности.

Может ли PerfectVector исправить заполненные отверстия в существующем SVG? PerfectVector полезен, когда вы можете вернуться к подходящему растровому исходнику и создать новую трассировку с видимыми нужными отверстиями. Он не исправляет составной контур, который редактор разъединил или импортёр проигнорировал. Такие связи исправляйте в векторном редакторе или целевой программе.

Источники

  1. W3C — отрисовка SVG 2 — Определяет nonzero, evenodd и начальное значение правила заливки.
  2. W3C — контуры SVG — Определяет контуры, подконтуры и замкнутую геометрию контуров.
  3. Adobe Illustrator — создание составных контуров — Описывает составные отверстия, правила заливки и изменение направления составляющих контуров.
  4. PerfectVector — преобразование изображения в вектор — Текущий процесс растра в SVG, используемый в случае повторной трассировки.

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

Ещё из блога

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