PerfectVector
Автор: Irene Kim

Логотипы SVG в Satori: графика в фирменной карточке

Встройте SVG-логотип в карточку Satori с явными размерами и самодостаточными данными изображения. Проверьте вложенную графику, затем отрисуйте отдельный PNG для передачи.

8 мин чтения
На этой странице

Чтобы поместить SVG-логотип в карточку Satori, передайте его как источник изображения, задайте ширину и высоту изображения и сохраните оригинальный SVG рядом со сгенерированной карточкой. В примере ниже SVG в base64 становится вложенным изображением в результате Satori. Он не становится новым набором редактируемых контуров логотипа во внешней карточке.

Satori создаёт SVG из ограниченного набора HTML и CSS. Его официальные рекомендации по изображениям советуют явные размеры и самодостаточные данные изображения, если последующее средство отрисовки будет создавать PNG. Это даёт два отдельных результата: скомпонованную карточку SVG и растровую копию для передачи.

Храните три файла с разными задачами

ФайлЧто содержитЧто менять в нём
Исходный SVG логотипаГеометрию и отверстие эмблемыФорму, цвет, границы исходника
SVG карточки SatoriКомпоновку карточки, надписи и встроенное изображение логотипаПрямоугольник графики, положение и содержимое карточки
Отрисованный PNGПиксели передаваемой карточкиСоздавать заново после изменений исходника

SVG <image> может ссылаться на другой SVG, как объясняет справочник MDN по image. Поэтому элемент image не означает автоматически, что встроенная графика растровая. Проверьте тип данных и декодированное содержимое, прежде чем диагностировать карточку по более общему списку проверок растровых изображений в SVG.

Держите мастер рядом с карточкой
Концептуальная иллюстрация мастера полого ромба и его копий разных размеров в простых фирменных карточках
Иллюстрация: храните редактируемую графику отдельно от композиции карточки. Проверка исходника и результата ниже относится к независимо созданному примеру Satori, а не к этой сгенерированной схеме.

Полный локальный пример

Этот стартовый пример использует стандартный импорт с выводом SVG из Satori 0.35.0 и resvg-js 2.6.2. В пустой рабочей папке установите закреплённые пакеты:

npm install --save-exact satori@0.35.0 @resvg/resvg-js@2.6.2

Создайте папку fonts и загрузите Abel-Regular.ttf и OFL.txt из каталога Abel в Google Fonts. Abel распространяется по SIL Open Font License 1.1; при распространении шрифта с примером сохраняйте прилагаемые уведомление и лицензию.

Сохраните следующий код как starter.mjs и запустите node starter.mjs. Он передаёт шрифт Satori, создаёт полый ромб и две карточки 600×320 с прямоугольниками графики 80×80 и 160×160. Файловые URL оставляют пути шрифта и результата относительными к сценарию.

import { readFile, writeFile } from 'node:fs/promises';
import satori from 'satori';
import { Resvg } from '@resvg/resvg-js';
 
const logo = `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128"><path d="M64 8 L120 64 L64 120 L8 64 Z M64 42 L86 64 L64 86 L42 64 Z" fill="#176b5b" fill-rule="evenodd"/></svg>`;
const src = `data:image/svg+xml;base64,${Buffer.from(logo).toString('base64')}`;
const font = await readFile(new URL('./fonts/Abel-Regular.ttf', import.meta.url));
await writeFile(new URL('./logo-master.svg', import.meta.url), logo);
 
for (const size of [80, 160]) {
  const svg = await satori({
    type: 'div',
    props: {
      style: { display: 'flex', width: 600, height: 320,
        backgroundColor: '#f6f2e8', color: '#152e29', fontFamily: 'Abel' },
      children: [
        { type: 'img', props: { src, width: size, height: size,
          style: { position: 'absolute', left: 24, top: 64 } } },
        { type: 'div', props: {
          style: { position: 'absolute', left: 220, top: 112, fontSize: 42 },
          children: 'CEDAR FIELD' } },
        { type: 'div', props: {
          style: { position: 'absolute', left: 220, top: 168, fontSize: 20 },
          children: 'A study in simple shapes' } },
      ],
    },
  }, {
    width: 600, height: 320,
    fonts: [{ name: 'Abel', data: font, weight: 400, style: 'normal' }],
  });
  const png = new Resvg(svg, { font: { loadSystemFonts: false } }).render().asPng();
  await writeFile(new URL(`./card-${size}.svg`, import.meta.url), svg);
  await writeFile(new URL(`./card-${size}.png`, import.meta.url), png);
}

Buffer.from(logo).toString('base64') кодирует созданные байты SVG в UTF-8 через API кодирования Buffer в Node. Префикс data:image/svg+xml;base64, определяет содержимое. Он меняет транспортное представление, а не геометрию логотипа.

Вызов Satori возвращает SVG карточки. Следующая строка передаёт этот SVG отдельному средству отрисовки PNG resvg-js. В примере нет удалённого URL изображения; локальный шрифт читается до отрисовки. Своё поведение удалённой загрузки или развёртывания проверяйте отдельно.

Что дали два реальных вызова

Мы запустили этот точный пример с закреплёнными пакетами, проверили оба выходных SVG и открыли каждый SVG и PNG в браузере. Все четыре файла карточек загрузились в 600×320. Надписи остались на тех же местах, а прямоугольник эмблемы удвоился.

Каждая карточка содержала один внешний <image> и два внешних элемента <path>. Эти два контура представляли надписи, а не внешние и внутренние очертания ромба. Декодирование base64-данных изображения восстановило точные исходные байты SVG: один контур, ноль элементов image и то же определение полого ромба. В этом запуске у карточки не было живых элементов <text>.

ПроверкаПрямоугольник графики 80×80Прямоугольник графики 160×160
Размеры карточки600×320600×320
Положение внешнего изображенияx24, y64x24, y64
Встроенный SVGИсходный мастер 128×128Те же байты мастера
Точные границы сплошного бирюзового цвета в PNG68×68 пикселей138×138 пикселей
Пиксель карточки в центре отверстияКремовый, альфа 255Кремовый, альфа 255

Строки границ окрашивания считают пиксели, точно совпадающие со сплошным бирюзовым цветом эмблемы. Они исключают сглаженные края. Это не размеры прямоугольника изображения: исходный ромб занимает координаты от 8 до 120, поэтому его математический охват масштабировался бы до 70 или 140 единиц внутри этих прямоугольников. Измеренные границы сплошного цвета были немного меньше.

Центр исходной эмблемы был прозрачным, с альфа-каналом 0 при отдельной отрисовке. В каждом конечном PNG карточки отверстие показывало непрозрачный кремовый фон: RGBA 246,242,232,255. Видимое отверстие и прозрачный пиксель конечной карточки — разные требования. Если нужен прозрачный фон для передачи, измените фон карточки и отдельно проверьте полученный альфа-канал.

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

Меняйте прямоугольник графики, не теряя исходник

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

Задайте оба размера изображения в нужных пропорциях. Наш исходник квадратный, и оба прямоугольника квадратные; выходное изображение использовало preserveAspectRatio="none", что здесь не изменило пропорции. Этот пример не проверяет прямоугольный логотип, принудительно помещённый в квадратное место. Меняйте по одной переменной компоновки, затем проверяйте фактический SVG и передаваемый PNG.

Держите надписи вне встроенного логотипа, если хотите менять их независимо. Текст карточки этого примера становится контурами в передаваемом SVG, но слова остаются редактируемыми в сценарии. Шрифтовой вход, графический вход и скомпонованный результат выполняют разные задачи; разбор шрифтов resvg описывает отдельный процесс отрисовки живого текста SVG.

Документация Satori по HTML и CSS описывает поддерживаемое подмножество и ограничения. Браузерный снимок существующей страницы не обещает, что этот движок компоновки воспроизведёт её точно. Начните с небольшой карточки и обычного импорта satori, затем добавьте свойства, действительно нужные дизайну.

Подготовьте логотип, начинающийся с пикселей

Если единственный логотип — PNG или JPG, а нужны редактируемые контуры, подготовьте SVG-логотип с PerfectVector, проверьте силуэт и внутренние отверстия и сохраните чистый SVG как мастер. Затем встройте его в карточку и проверьте оба размера графики и конечный PNG. Векторизация готовит графику, Satori выполняет композицию карточки. Существующий чистый SVG может сразу перейти к встраиванию. Руководство по векторизации объясняет различие исходника и результата.

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

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

Становится ли SVG-изображение редактируемыми контурами в карточке Satori? В этом примере логотип остаётся вложенным SVG-изображением. Его исходник из одного контура сохраняется в данных изображения; внешние контуры карточки — надписи. Храните оригинальный мастер для правки геометрии.

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

Делает ли прозрачное отверстие логотипа карточку прозрачной? Отверстие пропускает фон карточки. Наш кремовый фон непрозрачен, поэтому пиксель PNG в отверстии имеет альфа-канал 255. Если передаче нужен прозрачный фон карточки, проверяйте его отдельно.

Возвращает ли Satori PNG? Этот пример запрашивает у Satori строку SVG, затем отрисовывает её в PNG с resvg-js. Разделяйте эти этапы, чтобы независимо проверять компоновку и растровую передачу.

Источники

  1. Документация Satori по изображениям, компоновке и шрифтам — размеры изображений, самодостаточные входы, стандартный вывод SVG и поддерживаемый объём HTML/CSS.
  2. Выпуск Satori 0.35.0 — закреплённая версия исходного примера.
  3. Элемент image SVG — SVG-изображения могут ссылаться на другие файлы SVG.
  4. API кодирования Buffer в Node — операция кодирования base64 в стартовом примере.
  5. Использование resvg-js — отдельный этап отрисовки SVG в PNG.
  6. Лицензия шрифта Abel — происхождение шрифта, уведомление и лицензия распространения.

Для своего PNG- или JPG-логотипа подготовьте мастер SVG с PerfectVector и проверьте его очертания и внутренние отверстия. Сохраните мастер, затем проверьте его положение в SVG карточки и передаваемом PNG в размерах, которые планируете использовать.

Ещё из блога

PerfectVector

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

Без банковской карты