Могу ли я преобразовать текст SVG в путь, но повторно использовать глифы?

14

У меня есть SVG с грузом текста на нем. Это карта парковки с написанными на ней космическими номерами. Я отображаю это в веб-браузере, и благодаря замечательной небольшой ошибке в Firefox браузер неправильно отображает текст. Бу.

Поэтому я преобразовал текст в пути. Мы говорим о 4000 отдельных ярлыках. Может быть, 15 000 новых фигур теперь являются векторами. Это 4 МБ. Обычно вы можете утверждать, что это поддается сжатию, но я должен встроить этот SVG в HTML . Я добавляю CSS-изменения динамически, и это единственный способ получить поддержку кросс-браузера. Так или иначе, сырой - даже разведанный - вывод этого слишком велик, чтобы быть полезным.

Что меня поражает, так это то, что все эти пробелы имеют общие символы. Ноль через девять. Почему я включаю определение формы для каждого экземпляра каждого числа? Могу ли я их дублировать?

Я использую Inkscape, но я открыт для предложений.

Oli
источник
Есть ли у вас шанс поделиться файлом SVG, чтобы мы могли поэкспериментировать с ним?
JohnB
1
В чем именно ошибка (скриншот), и как вы экспортируете ее и загружаете в браузер? Есть хороший шанс, что вы можете исправить это с помощью некоторого стиля CSS или небольшого скрипта на странице, чтобы исправить / заменить текстовые элементы. Если это отображение динамической карты, возможно, вы захотите превратить его в реальную карту - большинство библиотек отображений браузера (и многие библиотеки на основе данных) имеют отличную поддержку для маркировки.
Brichins
1
Извините, SVG не моя, чтобы поделиться (она принадлежит клиенту), но об ошибке известно . По сути, это означает, что шрифты в SVG не будут уменьшаться до точки ... Что является серьезной проблемой, если вы полностью уменьшите масштаб на карте с тысячами пронумерованных парковочных мест. Они должны быть (например) ~ 0.08pt, и они на самом деле 13pt.
Оли
1
У вас неправильный номер ошибки, вы на самом деле ищете этот
Роберт Лонгсон
Возможно, вы захотите проверить это на подмножестве, но можете path|simplifyли вы вообще помочь? Строчные буквы «s» преобразуются в 28-точечный путь, упрощают его до 17 и накладывают на упрощенную и не упрощенную версии даже с увеличением, так что одна «s» заполняет экран, нет никакой разницы.
Крис Х

Ответы:

6

<use>Элемент позволяет повторно использовать объекты , определенные в другом месте в документе. Например, вы можете определить каждый глиф как, <symbol>а затем использовать их несколько раз. Вот хорошая статья о нем: структурирование, группирование и реферирование в SVG - The <g>, <use>, <defs>и <symbol>элементы .

Я не знаю, как сделать это непосредственно в Inkscape, тем более, особенно если речь идет о наборе текста, который у вас уже есть. Возможно, вам придется написать скрипт для постобработки SVG и найти все пути, которые можно использовать повторно.

Рахул
источник
<use>Было то , что я думал , когда я спросил это, скриптовый как. Кажется глупым, что нет ничего, что могло бы дублировать почти идентичную разметку.
Оли
@Oli не было ничего даже дедупликации одинаковой разметки; Я должен был написать свой собственный (и под идентичным я имею в виду байты; я их хэшировал и сравнивал хэши)
Крис Х
Я подумал над обедом, и мне кажется, что сценарий (python) в inkscape был бы подходящим вариантом. Сценарий должен начинаться с текста в виде текста и заменять его ссылками на <symbol>s (или, похоже, вы могли бы использовать <def>глифы текста к пути
Chris H
4

Есть несколько доступных вариантов сжатия, которые будут предлагать различные степени успеха. Чтобы проверить их, я создал графический файл, в котором было много повторяющегося текста. Нерасширенный, размер файла составляет 13,8 КБ. В развернутом виде размер файла составляет 1,42 МБ .

Хороший вариант: используйте SVGZ - 46,5 КБ

Сохранение расширенной иллюстрации в формате SVGZ дало мне выходной файл размером 46,5 КБ, который значительно меньше стандартного SVG. Обратите внимание, что эта поддержка может отличаться .

Лучший вариант: компресс с Scour - 21,1 КБ

Scour - это инструмент, который очистит и оптимизирует ваш SVG-файл для вас. С помощью команды «максимальное сжатие» scour -i input.svg -o output.svgz --enable-viewboxing --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=noneрасширенная обложка была уменьшена до 21,1 КБ. Недалеко от оригинального нераскрытого размера файла!

Johnb
источник
3
Чистка не сжимает, она просто удаляет мусор, и хотя она приносит мне немало пользы (учитывая огромное количество объектов), мои «4 МБ» были после чистки. Сжатый контент был бы хорош, но - и я должен был упомянуть об этом раньше - я должен указать SVG для проблем с таргетингом на браузер (а также с требованиями манипулирования внешним интерфейсом). Я знаю, я знаю, это больно, но поверь мне, когда я говорю, что сейчас мне больно больше D:
Оли
Я должен был сказать, что очищающая часть scourне сжимается. Он также может перебросить файл через gzip, но основное внимание уделяется минимизации идентификаторов и пробелов.
Оли
@ Правильно, отсюда мой осторожный выбор слова «оптимизировать» :) Облом, что ваш файл уже очищен, хотя ... ack!
JohnB
Я немного повозился в Illustrator; его вывод SVG действительно уважает символы. Вот быстрый пример . Это займет совсем немного усилий, но вы сможете создать сценарий Illustrator, который разбит ваш текст на отдельные символы и заменит их символами. Самое большое препятствие, которое я вижу, будет иметь дело с вращением. Если весь текст параллелен оси X, это не кажется сложным, но работа с текстом под углом может стать проблемой. Конечно, все это не очень полезно, если у вас нет иллюстратора
JohnB
3

Это решение в браузере или на сервере

Существует много разных способов оптимизации файлов SVG. Похоже, вы уже сделали немало.

Несколько ресурсов, которые я нахожу очень полезными, - это статья css-tricks , посвященная очень конкретным деталям. И конкретно, инструмент, который использует SVGO .

Если у вас много повторяющихся путей, я бы подумал об использовании javascript для динамического создания фигур. Существует пример здесь . Одним из направлений было бы иметь определенную функцию для каждого глифа и просто иметь каждый путь в элементе svg, созданный запросом для этой функции. Или возьмите полную строку и / или массив аргументов, чтобы создать свой встроенный svg. Это, конечно, предполагает, что ваши пути длиннее, чем длина кода, необходимого для запроса указанной функции (довольно простое предположение).

Люк
источник
1
Хотя в этом ответе представлено несколько возможных решений, SVGO представляется наиболее интересным. Он также может быть запущен в файле .svg для его оптимизации. Однако, похоже, в настоящее время не выполняется дедупликация пути. Если спрашивающий так или иначе заканчивает тем, что делал пользовательские сценарии, хорошей идеей было бы сделать это как усовершенствование SVGO.
Jpa
@jpa дедупликация перед (или во время) преобразованием в пути, безусловно, будет хорошим способом. Замените все вхождения текста char "1" на " <use xlink:href="#digit_one">где digit_oneпуть"
Chris H
@ChrisH Я не могу понять, почему нельзя потом так же плохо дедуплицировать. Просто нормализуйте все пути к источнику в начальной точке, возьмите хеш, используйте его, чтобы найти, если путь уже произошел. Конечно, не так элегантно, но должно работать и может быть проще в реализации, чем переопределение / выяснение всей логики размещения текста.
jpa
@jpa вы могли бы, но если нормализация источника привела к ошибкам округления, хеш не совпадет. Сценарий, о котором я думаю, будет вызывать inkscape text-to-path для разметки путей символов, но затем заменяет их ссылками на набор мастеров.
Крис Н
@jpa и ошибки округления реальны. На игрушечном примере первая квадратичная кривая нуля отличается на 1 в шестом десятичном знаке - достаточно, чтобы испортить хеширование
Крис Х
2

Здесь на очень высоком уровне то, что должен делать ваш скрипт. Не стесняйтесь использовать предпочитаемый вами язык и среду, это всего лишь отправная точка для логики, которая должна дать вам то, что вы ищете.

  • Просмотрите все текстовые элементы в XML-файле SVG, а для тех, которые имеют числовой текст (места парковки, вы не указываете, есть ли больше текста в вашем svg), измените автоматически созданный Inkscape идентификатор на строку с этой парковкой номер пятна. Inkscape нужны только уникальные идентификаторы, она генерирует неописательные идентификаторы, но будет учитывать и не изменять идентификаторы, созданные другим программным обеспечением или созданные вручную или измененные пользователем.
  • В таблице сохраните координаты x & y текстового элемента каждого места парковки.
  • Будь то в Inkscape или с помощью сценариев, преобразуйте весь текст места парковки в пути.
  • К цифрам 0-9 добавьте в файл SVG соответствующий <defs>раздел, определяющий информацию о пути для каждой цифры.
  • Прокрутите все <g>парковочные места и замените их<use xlink:href="#digit" x=x y=y />
  • прибыль

Я могу предвидеть некоторые осложнения, с которыми вам придется иметь дело, и удачи с ними.

  • Цикл должен будет разбить строку парковочных мест на 2 или более цифр, и соответствующий интервал между первой и последующими цифрами может быть сложным; это будет сильно зависеть от используемых вами шрифтов.
  • Вы не указываете, в какой ориентации находятся места для парковки, или если они даже на изогнутых установках. Из-за ручных смещений x, y для двухзначных чисел и более вам может понадобиться дополнительная логика, чтобы выяснить «ориентацию» места для парковки и как правильно отделить различные пути отдельных цифр от первой.

Надеюсь это поможет. Удачи.

botwhytho
источник