SVG в PDFKit: векторный логотип без растеризации
Вставьте полный SVG-логотип в документ PDFKit, задайте размер в пунктах и проверьте сохранённый PDF: контуры, отверстия, пропавшие свойства и встроенные изображения.
На этой странице
Чтобы поместить полный SVG-логотип в PDF, созданный в Node, используйте svg-to-pdfkit с PDFKit и передайте разметку SVG в SVGtoPDF(doc, svg, x, y, options). Встроенный doc.path() PDFKit принимает данные контура SVG, например значение атрибута d. Он не импортирует окружающий документ SVG, другие фигуры или стили.
Это различие важно для логотипа с несколькими цветами и отверстием в центре. Копирование одного контура может оставить часть иллюстрации за пределами результата. Преобразование всего логотипа в PNG сохраняет растровое изображение, но лишает вас вывода PDF на основе контуров, ради которого вы и начали.
Это руководство использует собственную эмблему, полный скрипт Node и проверку сохранённого PDF. Если у вас уже есть редактируемый векторный логотип, сохраните его как исходник. Восстановление векторной геометрии из растра выполняется до этого этапа импорта.
Выберите вставку полного SVG или одного контура
Документация PDFKit по векторной графике описывает парсер контуров и сопутствующие методы рисования. Отдельная библиотека SVG-to-PDFKit обрабатывает полную разметку SVG.
| Ваш исходник | Способ | Что вам ещё нужно сделать |
|---|---|---|
| Полный SVG с несколькими фигурами | SVGtoPDF(doc, svgText, x, y, options) | Проверить размеры, импортированные свойства и готовый PDF |
Значение d одного контура | doc.path(pathData) с последующей заливкой или обводкой | Самостоятельно задать оформление, преобразования и остальные фигуры |
| PNG или JPEG, который должен оставаться растром | doc.image(...) | Задать размещение и проверить эффективное разрешение изображения |
Документация PDFKit по изображениям перечисляет PNG и JPEG для doc.image(). Не считайте этот вызов средством импорта полного SVG.
Например, это корректное использование API контуров:
doc.save();
doc.fillColor('#eeaa42');
doc.path('M125 100L175 20L225 100Z').fill();
doc.restore();Он рисует треугольник нашей эмблемы в координатах контура. Он не восстанавливает бирюзовое кольцо или полоску из другой части исходного файла. Используйте способ работы с полным документом ниже, если эти части должны оставаться вместе.
Если PDF собирается в браузере через jsPDF, следуйте отдельному процессу SVG в jsPDF. Для документа из компонентов React используйте процесс SVG-логотипа в React-pdf. Для документов Python сравните проверки импорта и размеров ReportLab с прямым размещением SVG в fpdf2.
Запустите небольшой пример с фиксированными пакетами
Мы выполнили пример с PDFKit 0.20.2 и SVG-to-PDFKit 0.1.8. Это проверенная пара зависимостей; проверяйте свой результат после обновления любого пакета.
В новом проекте Node установите:
npm install --save-exact pdfkit@0.20.2 svg-to-pdfkit@0.1.8Сохраните это как logo.svg. Кольцо и его отверстие используют один контур с fill-rule="evenodd"; золотой треугольник и бирюзовая полоска — отдельные фигуры. Файл не содержит шрифтов, изображений или эффектов.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 120">
<path fill="#147d78" fill-rule="evenodd"
d="M110 60A50 50 0 1 1 10 60A50 50 0 1 1 110 60Z
M85 60A25 25 0 1 1 35 60A25 25 0 1 1 85 60Z"/>
<path fill="#eeaa42" d="M125 100L175 20L225 100Z"/>
<rect x="227" y="20" width="8" height="80" fill="#147d78"/>
</svg>Сохраните следующий код как place-logo.cjs в том же каталоге, затем запустите node place-logo.cjs:
const fs = require('node:fs');
const { finished } = require('node:stream/promises');
const PDFDocument = require('pdfkit');
const SVGtoPDF = require('svg-to-pdfkit');
async function main() {
const svg = fs.readFileSync('logo.svg', 'utf8');
const doc = new PDFDocument({ size: [800, 450], margin: 0 });
const output = fs.createWriteStream('logo.pdf');
doc.pipe(output);
const warnings = [];
SVGtoPDF(doc, svg, 72, 150, {
width: 180, height: 90,
preserveAspectRatio: 'xMinYMin meet',
warningCallback: message => warnings.push(message),
});
SVGtoPDF(doc, svg, 432, 150, {
width: 90, height: 45,
preserveAspectRatio: 'xMinYMin meet',
warningCallback: message => warnings.push(message),
});
doc.end();
await finished(output);
fs.writeFileSync('warnings.json', JSON.stringify(warnings, null, 2));
if (warnings.length) process.stderr.write(warnings.join('\n') + '\n');
}
main().catch(error => {
process.stderr.write(error.stack + '\n');
process.exitCode = 1;
});PDFKit создаёт поток. Вызов doc.end() завершает документ; затем скрипт ждёт завершения выходного потока перед возвратом. Вводная документация объясняет потоковую модель и размеры страниц в пунктах PDF: 72 пункта на дюйм.
Здесь две области размещения имеют размеры 180 × 90 pt и 90 × 45 pt, то есть 2.5 × 1.25 дюйма и 1.25 × 0.625 дюйма. Обе соответствуют пропорции 2:1 исходного viewBox. Нарисованные фигуры имеют отступы внутри viewBox, поэтому видимые границы меньше области размещения. При выравнивании логотипа с соседним текстом измеряйте холст и нарисованную графику отдельно.
Импортёр описывает width и height как начальную область просмотра. Его опция preserveAspectRatio управляет вписыванием в неё. Этот пример использует совпадающие пропорции и явные размеры, чтобы не зависеть от значения по умолчанию размером со страницу. Не используйте assumePt как универсальное исправление неожиданно маленького логотипа; сначала проверьте исходные размеры, viewBox и целевую область просмотра.
Проверьте PDF, затем его внешний вид
Наш минимальный logo.pdf имел одну страницу 800 × 450 pt. С pypdf 6.10.0 мы нашли 24 операции кубических кривых, две операции заливки по правилу чётности и ноль изображений страницы. Ресурсы страницы не содержали шрифтов или XObjects. Импортёр не выдал предупреждений для этого образца.
Эти результаты подтверждают узкий вывод: эта собственная эмблема без изображений была нарисована геометрией PDF в проверенных версиях. Они не подтверждают, что произвольные SVG превращаются в полностью векторные PDF. Логотип со встроенной фотографией всё ещё требует отдельной проверки.
Мы также отрисовали версию с подписями через Poppler. Она использует тот же SVG и два размера областей просмотра, а размещения перенесены в панели сравнения. Светлый фон панели остаётся видимым через оба кольца, а треугольник и узкая полоска — отдельными от кольца.

Одна чёткость при увеличении — слабое доказательство: достаточно крупный растр тоже может выглядеть резким. И наоборот, наличие операции кривой где-то в отчёте ничего не говорит о растеризации его логотипа. Изолируйте иллюстрацию в небольшом тестовом PDF перед проверкой документа, который также содержит фотографии и графики.
Для своего логотипа выполните обе проверки:
- Проверьте содержимое страницы PDF и ссылочные объекты средством анализа PDF. Ищите инструкции рисования в месте логотипа и учитывайте любые объекты изображений. Более сложные PDF могут помещать содержимое в Form XObjects, поэтому подсчёта только верхнего уровня не всегда достаточно.
- Откройте сохранённый PDF в нужном просмотрщике и сравните с исходником. Проверьте отверстие, отдельные цвета, обрезку, отступы и мелкие детали в фактическом размере готового документа.
Храните исходный SVG рядом с кодом генерации PDF. Если исходник лишь оборачивает пиксели, используйте диагностику встроенных изображений, прежде чем считать расширение SVG доказательством его геометрии.
Держите шрифты и эффекты в пределах проверенного процесса
SVG-to-PDFKit перечисляет фильтры и foreignObject среди неподдерживаемых возможностей. Он также описывает требования к регистрации шрифтов и обратным вызовам. Используйте явные презентационные атрибуты SVG для небольшого серверного логотипа и рассматривайте предупреждения вместе с отрисованным результатом. CSS, вычисленный браузером, — отдельная опция для переданного элемента SVG; это не то же самое, что передача разметки в данный скрипт Node. См. документацию библиотеки по возможностям и шрифтам.
Наша эмблема намеренно не использует текст. Для настоящих букв либо предоставьте и проверьте нужные шрифты, либо сохраните утверждённое начертание в контурах в векторном оригинале. Документация PDFKit по шрифтам описывает их встраивание и регистрацию. У текста документа и контуров логотипа разные потребности в редактировании; трассировка скриншота букв не определит исходный шрифт.
Если фирменный знак зависит от эффекта, который импортёр не воспроизводит, восстановите эффект подходящей геометрией либо выберите другой процесс экспорта и проверьте его. Растровая вставка тоже допустима, если внешний вид важнее сохранения контуров. Не описывайте этот выбор как экспорт с сохранением вектора.
Пример использует цвета RGB. Одно сохранение контуров не подтверждает соответствие цветовым требованиям типографии, PDF/X или допечатной подготовки. Уточните их у получателя; руководство по форматам логотипов помогает разделить редактируемый оригинал и файл для передачи.
Восстановите растровый логотип перед вставкой
Если исходный логотип существует только в PNG или JPG, векторизатор логотипов PerfectVector может подготовить вариант SVG до этапа PDFKit. Сравните контуры, мелкие отверстия и отдельные цветовые области с исходником, затем проведите этот вариант через те же проверки размещения и PDF.
Используйте исходный вектор, когда он доступен. Для повреждённых букв или точной фирменной геометрии заново наберите или перерисуйте нужную часть в редакторе. Руководство по векторизации логотипа объясняет это решение об исходнике. PerfectVector готовит контуры иллюстрации; PDFKit и его импортёр управляют размещением в документе. Тестовая эмблема статьи — векторная графика, написанная вручную, а не измеренный результат преобразования.
Частые вопросы
Может ли PDFKit импортировать полный SVG через doc.path()? Нет. Метод path читает данные контуров SVG. Используйте SVG-to-PDFKit для полного документа в этом процессе или самостоятельно рисуйте и оформляйте каждую фигуру.
Гарантирует ли SVG-to-PDFKit PDF без растровых изображений? Нет. Проверенная эмблема без изображений дала операции рисования и ноль изображений страницы. Проверяйте собственный исходник и экспортированный PDF, особенно если SVG содержит встроенные изображения или возможности вне поддерживаемого импортёром набора.
Почему видимый логотип меньше моих width и height? Эти опции определяют область просмотра импорта. Пустое пространство внутри исходного viewBox остаётся частью макета, а вписывание с сохранением пропорций может оставлять дополнительное пространство. Проверьте границы иллюстрации перед изменением запрошенного размера PDF.
Источники
- PDFKit — Vector graphics — Описывает разбор данных контуров SVG, операции оформления и графическое состояние.
- SVG-to-PDFKit — Usage and limitations — Определяет вставку полного SVG, параметры области просмотра, предупреждения, шрифты и поддерживаемые возможности.
- PDFKit — Images — Перечисляет растровые форматы, принимаемые API изображений.
- PDFKit — Getting started — Объясняет потоки документов, завершение и размеры страниц в пунктах PDF.
- PDFKit — Fonts — Описывает встраивание шрифтов и регистрацию именованных шрифтов.
Если логотип документа начинается с растра, подготовьте вариант SVG с PerfectVector, проверьте отверстия и контуры, затем разместите его в нужном размере PDF и проверьте сохранённый файл.
Ещё из блога

CairoSVG: экспорт SVG в PDF и PNG нужного размера
Преобразуйте SVG через CairoSVG, выберите ширину или масштаб, разберитесь с DPI и родительскими размерами, проверьте пиксели PNG и размер страницы PDF перед передачей.

Импорт SVG-логотипа в EasyEDA: изображение PCB или контуры панели?
Импортируйте логотип в EasyEDA Standard или Pro, не смешивая инструменты изображений PCB и контуры SVG панели. Проверьте редактор, слой, размер и графику перед экспортом.