DrawImage: примеры (JAVASCRIPT)

Canvas API: применение drawImage для отображения графики
Раздел: Canvas, Рисование
drawImage(image: CanvasImageSource, dx: Number, dy: Number): undefined

Основы функции drawImage

Метод drawImage() является частью Canvas API и применяется для отображения графических изображений или их частей на элементе <canvas>. Эта функция используется, когда требуется вывести растровое изображение на канву, включая операции по кадрированию, масштабированию и позиционированию.

Функция имеет три варианта синтаксиса:

  1. Полная форма: drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) — позволяет вырезать фрагмент из исходного изображения и разместить его на канве с изменением размера.
  2. Форма с масштабированием: drawImage(image, dx, dy, dWidth, dHeight) — выводит всё изображение с масштабированием до указанных размеров.
  3. Базовая форма: drawImage(image, dx, dy) — отображает изображение в исходном размере в заданных координатах.

Аргументы:

  • image — источник изображения (объект HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement или ImageBitmap).
  • sx, sy — координаты верхнего левого угла области вырезки в исходном изображении (только для полной формы).
  • sWidth, sHeight — ширина и высота вырезаемого фрагмента (только для полной формы).
  • dx, dy — координаты верхнего левого угла для размещения изображения на канве.
  • dWidth, dHeight — ширина и высота отображаемого изображения на канве (для масштабирования).

Возвращаемое значение: функция ничего не возвращает (undefined).

Простые примеры использования

Пример 1: базовое отображение

const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
const img = new Image();
img.src = 'picture.jpg';
img.onload = function() {
  ctx.drawImage(img, 10, 20);
};
Изображение отобразится в координатах (10,20) с оригинальными размерами.

Пример 2: масштабирование

ctx.drawImage(img, 50, 50, 200, 100);
Изображение будет растянуто до ширины 200 пикселей и высоты 100 пикселей, начиная с точки (50,50).

Пример 3: вырезка фрагмента

ctx.drawImage(img, 30, 40, 150, 120, 10, 15, 300, 240);
Из исходного изображения вырезается фрагмент из точки (30,40) размером 150x120 пикселей и отрисовывается на канве в точке (10,15) с размером 300x240 пикселей.

Похожие функции в JavaScript

putImageData() — позволяет записывать данные пикселей напрямую в канву. Используется для низкоуровневой работы с изображениями, например, при применении фильтров.

createPattern() — создает паттерн на основе изображения для заливки фигур или канвы. Подходит для фонового повторяющегося рисунка.

toDataURL() — генерирует data URL изображения с канвы. Применяется для сохранения или передачи изображения в формате base64.

ImageBitmap — интерфейс для оптимизированного отображения растровой графики. Рекомендуется для работы с текстурами в WebGL или при необходимости высокой производительности.

Аналоги функции в других языках

Python (библиотека Pillow)

from PIL import Image, ImageDraw
img = Image.open('picture.jpg')
draw = ImageDraw.Draw(img)
# Аналогом является метод paste()
overlay = Image.open('overlay.png')
img.paste(overlay, (10, 20))
Изображение overlay.png накладывается на основное в координатах (10,20).

PHP (библиотека GD)

$src = imagecreatefromjpeg('picture.jpg');
$overlay = imagecreatefrompng('overlay.png');
imagecopy($src, $overlay, 10, 20, 0, 0, imagesx($overlay), imagesy($overlay));
Функция imagecopy() выполняет операцию, аналогичную drawImage, накладывая одно изображение на другое.

C++ (библиотека OpenCV)

cv::Mat src = cv::imread('picture.jpg');
cv::Mat overlay = cv::imread('overlay.png');
cv::Rect roi(cv::Point(10, 20), overlay.size());
overlay.copyTo(src(roi));
Изображение копируется в указанную область основного изображения. Отличие в том, что OpenCV оперирует матрицами пикселей.

Типичные ошибки

1. Изображение не загружено

const img = new Image();
ctx.drawImage(img, 0, 0); // Ошибка
img.src = 'picture.jpg';
Функция drawImage не сработает, так как изображение ещё не загружено. Необходимо использовать событие onload.

2. Передача некорректного объекта

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.drawImage('picture.jpg', 0, 0); // Ошибка
Вместо строки с URL необходимо передавать объект изображения.

3. Координаты за пределами канвы

ctx.drawImage(img, -100, -200, 50, 50);
Изображение частично или полностью не видно, так как расположено за границами холста. Ошибки выполнения не происходит, но результат не отображается.

Изменения в последних версиях

Спецификация Canvas 2D API стабильна, существенных изменений в работе метода drawImage() не было. Однако, с появлением стандарта HTML5 Living Standard, функция поддерживает новые типы источников, такие как ImageBitmap и OffscreenCanvas, что улучшает производительность в веб-воркерах.

Добавлена возможность использования SVGImageElement в качестве источника, что расширяет сферу применения функции для векторной графики.

Расширенные примеры

Пример 1: создание спрайтовой анимации

Пример javascript
const sprite = new Image();
sprite.src = 'spritesheet.png';
let frameX = 0;
const frameWidth = 64;
function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(sprite, frameX * frameWidth, 0, frameWidth, 64, 100, 100, 128, 128);
  frameX = (frameX + 1) % 8;
  requestAnimationFrame(animate);
}
sprite.onload = animate;
На канве отображается анимированный спрайт, который меняет кадры из спрайтшита.

Пример 2: зеркальное отражение изображения

Пример javascript
ctx.save();
ctx.scale(-1, 1);
ctx.drawImage(img, -img.width - 10, 20);
ctx.restore();
Изображение отображается зеркально по горизонтали за счет трансформации контекста.

Пример 3: наложение водяного знака с прозрачностью

Пример javascript
const watermark = new Image();
watermark.src = 'watermark.png';
watermark.onload = function() {
  ctx.drawImage(img, 0, 0);
  ctx.globalAlpha = 0.5;
  ctx.drawImage(watermark, canvas.width - 150, canvas.height - 80, 120, 60);
  ctx.globalAlpha = 1.0;
};
На основное изображение накладывается полупрозрачный водяной знак в правом нижнем углу.

Пример 4: отрисовка видео на канве

Пример javascript
const video = document.getElementById('video');
function drawVideoFrame() {
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  requestAnimationFrame(drawVideoFrame);
}
video.addEventListener('play', drawVideoFrame);
Кадры видео отображаются на канве в реальном времени, создавая эффект видео-плеера.

JS drawImage function comments

En
DrawImage Draws an image, canvas, or video onto the canvas