Экспорт в PNG через toBase64Image()

Механизм получения изображения из canvas

Графики Chart.js рендерятся внутри HTML5 <canvas>, что позволяет напрямую извлекать растровое изображение без серверной обработки. После построения диаграммы доступ к пиксельному буферу осуществляется через методы canvas или экземпляра графика.

Ключевая функция для экспорта:

chart.toBase64Image()

Результат выполнения — строка в формате Data URL, содержащая PNG-изображение:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...

Эта строка может использоваться как:

  • источник изображения <img>
  • файл для скачивания
  • данные для отправки на сервер
  • содержимое PDF-экспорта

Базовый пример экспорта графика

const chart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['A', 'B', 'C'],
    datasets: [{
      label: 'Пример',
      data: [10, 20, 30]
    }]
  }
});

const base64Image = chart.toBase64Image();

const img = document.createElement('img');
img.src = base64Image;
document.body.appendChild(img);

Формирование PNG-файла для скачивания

Для преобразования base64 в загружаемый файл используется создание временной ссылки:

function downloadChart(chart, filename = 'chart.png') {
  const link = document.createElement('a');
  link.href = chart.toBase64Image();
  link.download = filename;
  link.click();
}

Механизм работает без серверной стороны, полностью на клиенте.


Параметры качества и масштабирования

Метод toBase64Image() поддерживает дополнительные настройки, влияющие на качество итогового изображения.

chart.toBase64Image('image/png', 1)

Параметры:

  • type — формат изображения (image/png, image/jpeg)
  • quality — коэффициент качества от 0 до 1 (для JPEG)

Для PNG параметр качества игнорируется, так как формат без потерь.


Увеличение разрешения изображения

По умолчанию экспорт соответствует размеру canvas. Для улучшения четкости используется масштабирование через device pixel ratio.

function exportHighResolution(chart, scale = 2) {
  const originalWidth = chart.width;
  const originalHeight = chart.height;

  const tempCanvas = document.createElement('canvas');
  tempCanvas.width = originalWidth * scale;
  tempCanvas.height = originalHeight * scale;

  const ctx = tempCanvas.getContext('2d');
  ctx.scale(scale, scale);

  ctx.drawImage(chart.canvas, 0, 0);

  return tempCanvas.toDataURL('image/png');
}

Такой подход повышает детализацию при печати и вставке в документы.


Отличия toBase64Image() и canvas.toDataURL()

Chart.js предоставляет обертку над стандартным API canvas:

Метод Назначение
chart.toBase64Image() Экспорт с учетом внутренних настроек Chart.js
canvas.toDataURL() Прямой снимок canvas без логики библиотеки

Различие проявляется при наличии:

  • плагинов
  • анимаций
  • кастомных рендер-слоев

Влияние анимации на экспорт

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

Чтобы получить статичное изображение, анимацию отключают:

const chart = new Chart(ctx, {
  type: 'line',
  data: {...},
  options: {
    animation: false
  }
});

Альтернативный вариант — временное отключение:

chart.options.animation = false;
chart.update();
const img = chart.toBase64Image();

Работа с прозрачностью фона

Canvas по умолчанию имеет прозрачный фон, что влияет на результат PNG.

Для задания фона используется плагин или кастомный рендер:

const chart = new Chart(ctx, {
  type: 'bar',
  data: {...},
  options: {
    plugins: {
      legend: { display: true }
    }
  },
  plugins: [{
    id: 'custom_bg',
    beforeDraw: (chart) => {
      const ctx = chart.ctx;
      ctx.save();
      ctx.fillStyle = '#ffffff';
      ctx.fillRect(0, 0, chart.width, chart.height);
      ctx.restore();
    }
  }]
});

Проблемы с CORS при экспорте

При использовании изображений в датасетах (например, иконок или фоновых картинок) canvas может быть “tainted”, если ресурсы загружены с внешнего домена без CORS-заголовков.

Последствия:

  • toBase64Image() выбрасывает ошибку безопасности
  • toDataURL() блокируется браузером

Решение:

image: {
  src: 'https://example.com/image.png',
  crossOrigin: 'anonymous'
}

И сервер должен отдавать:

Access-Control-Allow-Origin: *

Экспорт нескольких графиков

При работе с набором диаграмм возможна пакетная генерация изображений:

function exportCharts(charts) {
  return charts.map((chart, index) => ({
    id: index,
    image: chart.toBase64Image()
  }));
}

Результат может использоваться для формирования отчётов или загрузки на сервер.


Сохранение изображения на сервер

Base64-строка передается как обычные данные:

fetch('/upload', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    image: chart.toBase64Image()
  })
});

На сервере строка декодируется в бинарный PNG-файл.


Оптимизация размера результата

Base64 увеличивает размер данных примерно на 33% по сравнению с бинарным PNG. Для оптимизации применяются:

  • уменьшение разрешения canvas
  • отключение лишних элементов (grid, legend)
  • использование responsive: false
  • фиксированные размеры графика
options: {
  responsive: false,
  elements: {
    point: { radius: 0 }
  }
}

Использование в генерации отчетов

Экспорт через toBase64Image() часто применяется в системах:

  • аналитических дашбордах
  • генерации PDF-отчетов
  • email-рассылках с графиками
  • серверных рендерах через headless браузеры

Полученное изображение интегрируется как статический ресурс без зависимости от Chart.js.