Конвертация в растровые форматы

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

Создание элемента SVG и подготовка к конвертации

Для начала создаётся контейнер SVG с помощью SVG.js. Основной объект создаётся через метод SVG() и может быть присоединён к DOM:

const draw = SVG().addTo('#drawing').size(500, 500);

// Добавление примитивов
const rect = draw.rect(200, 100).attr({ fill: '#f06' });
const circle = draw.circle(100).attr({ fill: '#0f6', cx: 300, cy: 300 });

SVG.js позволяет добавлять любые фигуры, текст и группы элементов, которые потом можно экспортировать.

Получение строки SVG

Перед конвертацией в растровый формат необходимо получить текстовое представление SVG:

const svgElement = draw.node; // DOM-элемент SVG
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svgElement);

svgString содержит весь SVG-код, включая все атрибуты, стили и элементы. Он готов к использованию для последующего рендеринга на <canvas>.

Конвертация SVG в PNG через Canvas

Использование <canvas> является стандартным способом преобразования SVG в растровое изображение. Сначала создаётся объект Image и загружается строка SVG в формате Data URL:

const canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 500;
const ctx = canvas.getContext('2d');

const img = new Image();
img.onl oad = () => {
    ctx.drawImage(img, 0, 0);
    // Экспорт в PNG
    const pngData = canvas.toDataURL('image/png');
    console.log(pngData);
};
img.src = 'data:image/svg+xml;base64,' + btoa(svgString);

Ключевые моменты:

  • Использование btoa обеспечивает корректное кодирование SVG в Base64.
  • <canvas> автоматически растеризует SVG с сохранением размеров и цветов.
  • Размер canvas должен совпадать с размерами SVG, иначе изображение будет искажено.

Конвертация в JPEG и управление качеством

Для экспорта в JPEG используется метод toDataURL с указанием типа и качества:

const jpegData = canvas.toDataURL('image/jpeg', 0.9); // качество 90%

Особенности формата JPEG:

  • Поддерживает только непрозрачные изображения, поэтому прозрачность SVG будет заменена на белый фон.
  • Качество можно регулировать числом от 0 до 1.

Для сохранения прозрачности PNG предпочтительнее использовать именно PNG.

Автоматизация через функции

Для упрощения процесса конвертации удобно создавать универсальную функцию:

function svgToRaster(draw, format = 'image/png', width = 500, height = 500, quality = 1.0) {
    return new Promise((resolve, reject) => {
        const svgString = new XMLSerializer().serializeToString(draw.node);
        const img = new Image();
        const canvas = document.createElement('canvas');
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext('2d');

        img.onl oad = () => {
            ctx.clearRect(0, 0, width, height);
            ctx.drawImage(img, 0, 0, width, height);
            resolve(canvas.toDataURL(format, quality));
        };
        img.oner ror = reject;

        img.src = 'data:image/svg+xml;base64,' + btoa(svgString);
    });
}

// Пример использования
svgToRaster(draw, 'image/png').then(dataUrl => console.log(dataUrl));

Такая функция обеспечивает масштабируемость и удобство при работе с множеством SVG-элементов и разными форматами.

Работа с большими SVG и оптимизация

  • Перед конвертацией рекомендуется использовать viewBox для корректного масштабирования.
  • Для сложных SVG с большим количеством элементов можно предварительно сгруппировать элементы через group() в SVG.js, чтобы уменьшить количество отдельных отрисовок на Canvas.
  • Минимизация SVG (удаление лишних атрибутов и пробелов) ускоряет преобразование и снижает размер Base64-кода.

Использование сторонних библиотек для экспорта

Хотя прямой подход через Canvas покрывает большинство случаев, иногда используются библиотеки вроде canvg для поддержки сложных фильтров, градиентов и CSS, которые браузер может некорректно рендерить через <canvas>.

import { Canvg } from 'canvg';

const canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 500;
const ctx = canvas.getContext('2d');

const v = await Canvg.fromString(ctx, svgString);
await v.render();

const pngData = canvas.toDataURL('image/png');

Преимущества использования Canvg:

  • Полная поддержка SVG-фильтров, градиентов и текста.
  • Совместимость с IE и старыми браузерами.
  • Возможность рендерить SVG в Node.js для серверной генерации изображений.

Практические рекомендации

  • Для динамических графиков или интерактивных диаграмм важно обновлять draw.node перед конвертацией.
  • Контролировать размеры и соотношение сторон через viewBox и canvas.width/height.
  • Проверять поддержку CSS-стилей, так как Canvas не всегда корректно интерпретирует внешние стили.

Конвертация SVG в растровые форматы с помощью SVG.js и Canvas предоставляет гибкий, кросс-браузерный и программно управляемый способ экспорта графики без необходимости использования серверных решений.