Шрифты SVG в resvg: загрузите нужную гарнитуру
Исправьте отсутствующий или подмененный текст SVG в resvg, явно задав файлы шрифтов. Запустите пример Node, сравните три результата и сохраните редактируемый оригинал.
На этой странице
Чтобы надежно отображать шрифты SVG в resvg, передайте файлы шрифтов средству отрисовки и используйте названия их семейств в SVG. Для нативной привязки Node @resvg/resvg-js это означает настройку fontFiles; задайте loadSystemFonts: false, если хотите проверить, какие именно шрифты получает ваша задача. Пример Node проекта показывает эту настройку.
PNG может выглядеть завершенным, но использовать неверную гарнитуру. Проверяйте формы букв даже при успешном выполнении команды экспорта.
Три набора шрифтов, один SVG
Мы создали небольшую горную эмблему из контуров и поместили рядом обычный текст PINE & FIELD. SVG запрашивает семейство Abel с обычным начертанием. Мы отрисовали один исходник трижды с @resvg/resvg-js 2.6.2, Node 22.19.0 и macOS arm64. Поиск системных шрифтов был отключен во всех случаях.
| Переданные файлы шрифтов | Наблюдаемый результат |
|---|---|
| Никаких | Эмблема из контуров отобразилась; надпись исчезла. |
| Только Anton | Надпись отобразилась явно отличающимся, более тяжелым начертанием. |
| Abel | Отобразились задуманные тонкие буквы. |

Эти наблюдения описывают этот образец и конфигурацию. Они не устанавливают, какой запасной шрифт выберет другой набор шрифтов, привязка или версия. Полезный диагностический вывод проще: отсутствие запрошенного семейства может привести к отсутствию текста или к правдоподобно выглядящей подмене.
Загрузите локальный шрифт в resvg-js
Этот пример использует нативный пакет Node, а не отдельный пакет WebAssembly. Определения типов этой версии привязки перечисляют fontFiles, fontDirs и loadSystemFonts внутри параметра font.
В новой рабочей папке установите использованную здесь версию:
npm install --save-exact @resvg/resvg-js@2.6.2Скачайте Abel-Regular.ttf и сопровождающий OFL.txt из каталога Abel в Google Fonts. Храните оба в подпапке fonts. Abel распространяется под SIL Open Font License; сохраняйте лицензию вместе со шрифтом при распространении этого примера.
Сохраните это как label.svg:
<svg xmlns="http://www.w3.org/2000/svg"
width="880" height="240" viewBox="0 0 880 240">
<rect width="880" height="240" fill="#f6f2e8"/>
<path d="M46 155 L96 57 L147 155 Z" fill="#176b5b"/>
<path d="M75 155 L112 88 L166 155 Z" fill="#81ab78"/>
<text x="195" y="151" font-family="Abel"
font-size="82" font-weight="400" fill="#152e29">
PINE & FIELD
</text>
</svg>Затем сохраните render.mjs рядом с SVG:
import { access, readFile, writeFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import { Resvg } from '@resvg/resvg-js';
const fontFile = fileURLToPath(
new URL('./fonts/Abel-Regular.ttf', import.meta.url)
);
await access(fontFile);
const svg = await readFile(new URL('./label.svg', import.meta.url));
const renderer = new Resvg(svg, {
font: {
loadSystemFonts: false,
fontFiles: [fontFile],
},
});
const png = renderer.render().asPng();
await writeFile(new URL('./label.png', import.meta.url), png);Запустите node render.mjs. URL файлов задают пути ввода и вывода относительно скрипта, поэтому смена рабочей папки терминала не меняет открываемый шрифт. access() дает прямую ошибку файловой системы, если шрифт отсутствует или недоступен; он не проверяет содержимое шрифта.
Чтобы воспроизвести контрольные варианты, оставьте SVG неизменным. Для первой строки используйте пустой массив fontFiles. Для второй скачайте Anton-Regular.ttf из каталога Anton в Google Fonts, сохраните лицензию и передайте этот файл вместо Abel. Проверьте каждый PNG, прежде чем менять что-либо еще.
Сопоставляйте название семейства, а не имя файла
Abel-Regular.ttf — путь к файлу. Abel — семейство, запрашиваемое SVG. Запись font-family="Abel-Regular.ttf" не указывает средству отрисовки открыть этот файл.
Атрибут SVG font-family принимает названия семейств или обобщенные семейства, а при нескольких — приоритетный список. У него также есть аналог CSS: соответствующее объявление CSS font-family имеет приоритет над атрибутом представления.
Для собственного изображения проверьте вместе три вещи:
- Семейство: название, записанное внутри шрифта и запрошенное SVG.
- Стиль и насыщенность: соответствует ли переданное начертание задуманным буквам.
- Символы: содержит ли шрифт буквы и символы реальной надписи.
Успешный readFile доказывает только чтение байтов. Видимое слово доказывает только отрисовку каких-то букв. Ни то ни другое не доказывает, что выбранное начертание совпадает с вашим дизайном.
Более общая диагностика текста и контуров описана в статье о смене шрифтов SVG после экспорта.
Проверьте те же входные данные в среде экспорта
Считайте шрифт входными данными задачи обработки изображения. Включите необходимый файл шрифта в развертывание или комплект задачи, затем убедитесь, что вычисленный путь указывает на него в этой среде. Гарнитуру, установленную на дизайнерском ноутбуке, легко упустить при сборке серверной задачи.
Начните с отключенного поиска системных шрифтов и минимального явного списка шрифтов, покрывающего тестовую надпись. Когда этот результат станет правильным, проверьте реальные слова, пунктуацию, насыщенности и языки вашего изображения. Наша латинская надпись обычного начертания не проверяет другие письменности или сложные семейства шрифтов.
Если буквы все еще выглядят неверно, проверьте исходник на переопределения CSS и стили вложенных <tspan>. Если и эмблема, и надпись неожиданно обрезаются или масштабируются, исследуйте границы SVG и размеры растра отдельно. Наше пошаговое руководство по размерам CairoSVG рассматривает это различие в другом средстве отрисовки; его параметры специфичны для CairoSVG.
При передаче отчета об ошибке или воспроизводимой задачи экспорта включите SVG, точную версию привязки, имена и версии файлов шрифтов, параметры отрисовки и ожидаемое изображение. Учитывайте разрешения на распространение шрифтов при упаковке файлов.
Храните редактируемый исходник рядом с PNG
Код выше записывает PNG. Это растровый файл для передачи; видимые буквы больше не являются редактируемым текстом SVG. Сохраните label.svg и входные файлы шрифтов как исходник для будущих изменений формулировки.
Если получателю нужен векторный логотип с фиксированными буквами, подготовьте отдельную копию SVG с текстом в контурах в векторном редакторе и проверьте ее там. Сохраните оригинал с обычным текстом. Наше руководство по форматам файлов логотипов объясняет, какие исходные и передаваемые файлы решают разные задачи.
Если нужная эмблема существует только в PNG или JPG, векторизатор логотипов PerfectVector может помочь восстановить векторную графику для этой части дизайна. Проверьте полученные контуры, удалите ненужные трассированные буквы и заново наберите надпись известным шрифтом перед экспортом resvg. Векторизация не определяет исходный шрифт и не восстанавливает обычный текст. Руководство по векторизации изображений объясняет, что меняет это преобразование.
Частые вопросы
Почему текст исчезает, когда я отключаю системные шрифты? В нашем тесте без шрифтов средство отрисовки не получило начертание для обычной надписи, поэтому появилась только графика из контуров. Явно загрузите подходящий шрифт и проверьте его семейство, стиль и набор символов.
Можно ли использовать имя файла шрифта как название семейства в SVG? Используйте название семейства шрифта в SVG. Локальное имя файла передавайте отдельно через fontFiles. Переименование файла шрифта не меняет его внутреннее название семейства.
Превращает ли resvg мой логотип PNG в редактируемый SVG? Пример здесь отрисовывает SVG в PNG. Он не векторизует растровый логотип. При необходимости восстановите эмблему через векторизацию, затем добавьте редактируемый текст и сохраните этот SVG как оригинал.
Источники
- resvg-js — Version 2.6.2 README — Использование нативного Node и явная загрузка шрифтов.
- resvg-js — Version 2.6.2 type definitions — Конфигурация шрифтов и API отрисованного изображения.
- MDN — SVG font-family — Списки семейств и приоритет CSS.
- Google Fonts — Abel — Обычное начертание и лицензия для задуманной надписи.
- Google Fonts — Anton — Шрифт и лицензия для контрольной подмены.
Если растровая эмблема задерживает работу, векторизуйте графику логотипа, проверьте края в редакторе и добавьте надпись обычным текстом. Затем выполните отрисовку с явным файлом шрифта и сравните PNG с оригиналом перед передачей.
Ещё из блога

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

Текст SVG foreignObject: пропавшие подписи при экспорте
Исправьте подписи SVG, которые видны в браузере, но исчезают при экспорте. Сравните foreignObject с обычным текстом SVG, проверьте пространства имён и сохраните иллюстрацию.