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

SVG в fpdf2: сохраните контуры в PDF на Python

Поместите SVG-логотип в PDF на Python через fpdf2, задайте размер, проверьте сохранённые контуры и найдите причину пропавшего текста или фигур перед переходом к растру.

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

Используйте pdf.image("logo.svg", x=20, y=20, w=60), чтобы поместить SVG в документ fpdf2. Поддерживаемая геометрия SVG становится контурами рисования PDF. Сначала преобразовывать логотип в PNG не требуется. Официальная документация по SVG описывает этот прямой способ и его ограничения.

Если сам формат вам незнаком, руководство по файлам SVG объясняет контуры и контейнеры изображений. Даже успешный импорт нужно проверять. Файл может содержать встроенные пиксели, зависеть от возможностей, которые импортёр не воспроизводит, или иметь пустое пространство вокруг рисунка. Это руководство создаёт небольшой собственный логотип, размещает его с явным размером и проверяет полученный PDF. Если есть векторный оригинал, сохраните его; восстановление иллюстрации из PNG или JPG — отдельный предшествующий этап.

Начните с известного SVG и фиксированной версии fpdf2

Мы выполнили пример с Python 3.12 и fpdf2 2.8.8. Это проверенная версия, а не обещание одинакового поведения всех последующих выпусков. Официальная страница пакета на PyPI описывает установку дистрибутива с именем fpdf2; импорт в Python называется fpdf.

Используйте новое окружение, чтобы пример не зависел от пакетов другого проекта:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install "fpdf2==2.8.8"

В Windows вместо этого активируйте окружение командой .venv\Scripts\activate. Сохраните эту собственную прямоугольную эмблему как logo.svg:

<svg xmlns="http://www.w3.org/2000/svg"
     width="120" height="80" viewBox="0 0 120 80">
  <path fill="#137d89" fill-rule="evenodd"
        d="M10 10H110V70H10Z M30 25H90V55H30Z"/>
</svg>

Здесь два замкнутых подконтура. Внешний прямоугольник залит, а внутренний становится отверстием благодаря правилу заливки evenodd. Шрифты, изображения и эффекты не используются, поэтому первую проверку легко диагностировать.

Сохраните следующий код как place_logo.py рядом с SVG:

from pathlib import Path
from fpdf import FPDF
 
folder = Path(__file__).resolve().parent
pdf = FPDF(unit="mm")
pdf.add_page()
pdf.image(str(folder / "logo.svg"), x=20, y=20, w=60)
pdf.output(str(folder / "logo.pdf"))

Запустите python place_logo.py. Откройте logo.pdf и проверьте бирюзовую прямоугольную рамку возле левого верхнего угла: в её центре должна просвечивать страница.

Различайте холст SVG и нарисованный логотип

Исходный холст имеет пропорции 3:2: ширина 120 единиц, высота 80. При w=60 этот пример занимает холст 60 × 40 мм. Рисунок отступает от краёв холста на 10 исходных единиц, поэтому его закрашенный внешний прямоугольник имеет размер 50 × 30 мм и начинается в 25, 25 мм на странице. Это расчёты по координатам и масштабу данного образца.

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

Руководство fpdf2 по изображениям объясняет обработку размеров и возможность сохранять пропорции внутри заданной рамки. В первом примере задайте только ширину. Если позже укажете оба размера, специально проверьте нужное вписывание, не предполагая одинаковые пропорции у всех исходников.

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

Убедитесь, что сохранённый PDF содержит контуры

Предварительный просмотр PDF показывает внешний вид, но и растровое изображение может выглядеть чётким при небольшом увеличении. Проверьте также сам файл. Мы проверили изолированный пример с pypdf 6.1.1:

python -m pip install "pypdf==6.1.1"
from pathlib import Path
from pypdf import PdfReader
 
folder = Path(__file__).resolve().parent
page = PdfReader(folder / "logo.pdf").pages[0]
print("Page images:", len(page.images))
print(page.get_contents().get_data().decode("latin-1"))

Наш вывод показал ноль изображений на странице. Декодированное содержимое включало прямоугольные контуры, выраженные операциями перемещения, линии и замыкания, за которыми следовало f* — операция заливки по правилу чётности. Вместе с отображаемым отверстием это подтверждает, что данный образец без изображений сохранился как геометрия рисования в PDF.

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

Диагностируйте пропавшую графику в вашей установленной версии

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

СимптомПервая проверкаПолезный следующий шаг
Страница пустаяПуть к файлу, размещение, размеры и предупреждения импортёраПроверить простую эмблему с явными координатами
Логотип кажется слишком маленькимПустое пространство внутри исходного холстаСравнить нарисованные границы с viewBox
Центр заполняетсяСтруктура составного контура и правило заливкиСохранить отверстие при редактировании или экспорте
Буквы пропали или изменилисьУстановленная версия, выбор шрифта и свойства текстаПроверить отдельный текстовый образец или использовать утверждённые буквы логотипа в контурах
Украшение исчезаетНеподдерживаемые возможности SVGУдалить эту возможность из копии и сравнить результат
PDF чёткий, но может содержать пикселиВстроенные изображения в исходнике и PDFПроверить структуру файла вместе с предварительным просмотром

К старым ответам здесь стоит относиться внимательно. Наша отдельная проверка версии 2.8.8 с простым элементом <text> дала извлекаемый текст HELLO, а прямоугольник с простым линейным градиентом успешно экспортировался. Эти узкие проверки не подтверждают полной совместимости текста SVG, шрифтов, CSS или градиентов. Но они показывают, почему старое утверждение о неподдержке всего текста SVG или всех градиентов может привести к ненужной растеризации.

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

Используйте растровый вариант, когда этого требует результат

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

Для фирменного логотипа лучше могут подойти утверждённые буквы в контурах или более простой векторный экспорт. Для редактируемого текста документа оставьте обработку шрифтов и текста в процессе подготовки документа. Трассировка скриншота предложения не восстанавливает его типографику и не делает текст выделяемым.

Если ваш существующий код PDF использует другую библиотеку Python, процесс работы с SVG в ReportLab имеет собственные проверки импорта и размеров. Смена библиотеки — отдельное решение реализации, поэтому проверьте реальную проблемную возможность перед перестройкой документа.

Подготовьте растровую иллюстрацию до этапа PDF

Если остался только логотип PNG или JPG, векторизатор логотипов PerfectVector может подготовить вариант SVG перед импортом через fpdf2. Сравните контуры, небольшие отверстия и цветовые области с исходником, затем проведите этот вариант через те же проверки размещения и PDF.

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

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

Может ли fpdf2 вставить SVG напрямую? Да. Передайте SVG-файл методу image и задайте размещение и размер. Поддерживаемая геометрия может стать контурами PDF, но для своей иллюстрации проверяйте экспортированный файл и внешний вид.

Поддерживает ли fpdf2 текст SVG? Наш простой текстовый тест сработал в fpdf2 2.8.8. Это не гарантирует работу любого шрифта, способа размещения или текста вдоль контура. Проверьте установленную версию и именно те буквы, которые используются в документе.

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

Стоит ли преобразовать PNG-логотип в SVG перед добавлением? Только если вам нужны редактируемые контуры, а иллюстрация подходит для трассировки. Оставляйте фотографии растровыми и используйте исходный векторный логотип, если он есть. Перед вставкой проверьте трассированный вариант.

Источники

  1. fpdf2 — SVG — Описывает прямую вставку SVG, поддержку возможностей и журналы предупреждений.
  2. fpdf2 — Images — Объясняет размещение изображений, размеры и вписывание с сохранением пропорций.
  3. fpdf2 — PyPI package — Определяет устанавливаемый дистрибутив и соглашение об импорте в Python.

Есть только растровый логотип? Подготовьте вариант SVG с PerfectVector, проверьте его контуры и отверстия, затем разместите в нужном размере через fpdf2 и проверьте сохранённый PDF.

Ещё из блога

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