Антиалиасинг в HTML5 canvas: метод drawImage

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Сглаживание на HTML5-холсте осуществляется путём установки свойства ctx.imageSmoothingEnabled в true. Свойство ctx.imageSmoothingQuality позволяет дополнительно настроить качество.

JS
Скопировать код
const ctx = document.getElementById('canvas').getContext('2d');
// Делаем изображение гладким, как джазовую мелодию 🎵
ctx.imageSmoothingEnabled = true;
// Стандарт качества — только самый высокий 🔝
ctx.imageSmoothingQuality = 'high'; // 'low', 'medium', 'high'

// А после загрузки рисуем наше произведение искусства 🖼️
const img = new Image();
img.onload = () => ctx.drawImage(img, 0, 0);
img.src = 'image.jpg';

Всего несколько строк кода – и перед вами значительное улучшение качества изображения.

Кинга Идем в IT: пошаговый план для смены профессии

Совершенствование антиалиасинга

Разберёмся, как достичь идеально гладких изображений с применением современных техник сглаживания.

Предварительное размытие: ваше секретное оружие для гладких краёв

Даже наивысшие стандарты качества иногда требуют дополнительных улучшений. Примените размытие к изображению перед его размещением на холсте для обеспечения мягких переходов.

JS
Скопировать код
// Добавляем немного "кинематографического" размытия 🎬
ctx.filter = 'blur(1px)'; // Смело экспериментируйте с размытием
img.onload = () => ctx.drawImage(img, 0, 0);

Не забудьте проверить существование ctx.filter перед его использованием: typeof ctx.filter !== 'undefined.

Постепенное уменьшение размера: искусство делать всё гладко

Постепенное уменьшение размера — великолепная техника антиалиасинга. Главное — быть тщательным и внимательным.

JS
Скопировать код
function stepDownScale(context, image, steps) {
  // Шаг 1: создаём новый холст. Что здесь может пойти не так? 🤷‍♂️
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext('2d');
  canvas.width = image.width;
  canvas.height = image.height;
  ctx.drawImage(image, 0, 0);
  
  // Шаг 2: Постепенно уменьшаем размер, словно спускаемся по лестнице 🪜
  for (let i = 0; i < steps; i++) {
    canvas.width *= 0.5;
    canvas.height *= 0.5;
    ctx.scale(0.5, 0.5);
    ctx.drawImage(canvas, 0, 0);
  }
  
  return canvas; // Получаем на выходе холст с гладким изображением
}

Чтобы определить нужное количество шагов, используйте формулу: Math.log2(Math.max(image.width / targetWidth, image.height / targetHeight)).

Учёт особенностей браузеров

В каждом браузере есть свои нюансы. Необходимо учитывать эти ограничения, так как браузеры работают по-разному. Использование библиотеки, например pica, может быть хорошим выходом.

Столкновение с реальностью прямого масштабирования

Прямое масштабирование может показаться простым, но оно не всегда обеспечивает нужное качество антиалиасинга. Поэтому техники, такие как предварительное размытие или постепенное уменьшение размера, могут оказаться более предпочтительными.

Визуализация

Сглаживание обеспечивает мягкие переходы между цветами. Посмотрим на примеры:

До сглаживания: После сглаживания: 🐤🎂🔥 🐥🎂🕯️ Празднование дня рождения на грани катастрофы Спокойный день рождения

Как видите, сглаживание делает процесс восприятия более приятным.

Расширение вашего арсенала техник сглаживания

Вот несколько приёмов, которые помогут сделать ваши изображения ещё лучше.

Вторичный холст: больше обычно лучше

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

JS
Скопировать код
let offscreenCanvas = document.createElement('canvas');
// На этом холсте так много пиксельного пространства, что оно выходит за экран 💻
let offscreenCtx = offscreenCanvas.getContext('2d');

// Чем больше пространство, тем гладче получается изображение 🌇
offscreenCanvas.width = img.naturalWidth * 2;
offscreenCanvas.height = img.naturalHeight * 2;
offscreenCtx.drawImage(img, 0, 0, offscreenCanvas.width, offscreenCanvas.height);

Используйте внекадровый холст для получения необходимого размера на целевом холсте.

Качественное преобразование с использованием toDataURL

Метод toDataURL позволяет выполнять высококачественное преобразование изображений. Перевод пикселей в строку base64 — это целое искусство.

JS
Скопировать код
function getBase64Image(canvas) {
  // Прощайте, пиксели, мир строк приветствует вас 👋
  return canvas.toDataURL("image/jpeg");
}

Поддержание качества с помощью свойства background-image

Свойство CSS background-image помогает поддерживать качество при масштабировании.

JS
Скопировать код
// Применяем фоновое изображение для холста 🎭
canvas.style.backgroundImage = `url(${img.src})`;

Полезные материалы

  1. HTMLCanvasElement: метод getContext() – Web APIs | MDN — Важно разбираться в контексте применения.
  2. Ускорение работы с пикселями холста с помощью Typed Arrays – Mozilla Hacks – Блог веб-разработчика — Как увеличить скорость рендеринга на холсте 💥.
  3. Отключение интерполяции при масштабировании <canvas> – Stack Overflow — Обсуждение методов борьбы с антиалиасингом при использовании drawImage().
  4. Dev.Opera — Основы работы с HTML5 Canvas — Обзор основных аспектов работы с холстом.
  5. HTML Стандарт — Основной документ, посвящённый элементу Canvas.
  6. Масштабирование SVG | CSS-Tricks — Важность масштабирования не ограничивается векторной графикой.