Get to know MDN better
This page was translated from English by the community. Learn more and join the MDN Web Docs community.
До сих пор мы создавали наши собственные фигуры и применяли стили к ним. Одна из самых впечатляющих функций <canvas> это возможность использования изображений. Они могут быть использованы для динамического композитинга фото или как фоны графиков, для спрайтов в играх, и так далее. Внешние изображения могут быть использованы в любых поддерживаемых браузером форматах, таких как PNG, GIF, или JPEG. Вы можете даже использовать изображение, произведённое другими canvas элементами на той же странице как источник!
Импортирование изображений в canvas в основном состоит из 2 этапов:
Давайте посмотрим как это сделать.
Canvas API может использовать все перечисленные далее типы данных как источник изображения:
HTMLImageElementЭти изображения созданы, используя конструктор Image(), также как все<img> элементы.
HTMLVideoElementИспользуя HTML <video> элемент как источник изображения захватывает текущий кадр из видео и использует его как изображение.
HTMLCanvasElementВы можете использовать другой <canvas> элемент как источник изображения.
Эти источники совместно именуемые по типу CanvasImageSource.
Есть несколько способов, чтобы получить изображения для использования на холсте.
Мы можем получить ссылку на изображение, на той же странице, на canvas с используя один из способов:
Использование crossorigin атрибута <img> элемент (отображается HTMLImageElement.crossOrigin свойства), вы можете запросить разрешение на загрузку другого домена для использования в drawImage(). Если хостинг домен разрешает доступ к междоменному изображению, то изображение может быть использовано в вашем canvas без without tainting it;иначе он может испортить ваш canvas.
Как и с обычными изображениями, мы можем получить доступ к другим canvas элементам используя либо document.getElementsByTagName() либо document.getElementById() метод. Проверьте, что в canvas источнике уже что-то нарисовано, прежде чем использовать его в целевом изображении canvas.
Одним из удобных способов было бы использование второго элемента canvas в качестве миниатюры другого большего изображения canvas.
Другой способ это создать новые HTMLImageElement объекты в нашем скрипте. Чтобы это сделать, вы можете использовать удобный Image() конструктор:
Когда этот скрипт выполнится, изображение начнёт загружаться.
Если вы попытаетесь вызвать функцию drawImage() перед тем как изображение загрузится, то скрипт ничего не сделает (или, в старых браузерах, может даже выдать исключение). Поэтому вам необходимо использовать событие load, чтобы вы не пытались сделать это прежде, чем изображение загрузится:
Если вы используете только одно стороннее изображение, то этот метод может быть хорошим примером, но если нужно следить за несколькими изображениями, то необходимо придумать что-то более умное. Хотя поиски тактики проверки загрузки изображений выходят за пределы этого обучающего курса, вы должны об этом помнить.
Другой возможный способ включить изображение это через data: url. Data URLs позволяет вам полностью определить изображение как Base64 кодированную строку символов прямо в ваш код.
Одним из преимуществ data URLs это то что полученное изображение доступно сразу без других запросов туда-обратно на сервер. Другое потенциальное преимущество в том, что также можно инкапсулировать всё в одном файле все ваши CSS, JavaScript, HTML, и изображения, что делает его более портативным в других местах.
Некоторые недостатки этого метода в том что ваше изображение не кешировано, и для изображений с большим размером кодирование url может стать очень долгим процессом.
Вы также можете использовать кадры из видео представленных <video> элементом (даже если видео не видно). Например, если у вас есть <video> элемент с ID "myvideo", вы можете сделать:
Эта функция вернёт HTMLVideoElement объект для этого видео, который, как мы упоминали ранее, является одним из объектов, который можно использовать как CanvasImageSource.
Как только мы получили ссылку на источник объекта изображения, мы можем использовать метод drawImage() для включения его в canvas. Как мы увидим далее, метод drawImage() перегружен и у него есть несколько вариантов. В базовом варианте он выглядит как:
drawImage(image, x, y)Рисует изображение, указанное в CanvasImageSource в координатах (x, y).
Примечание: SVG изображения должны указывать ширину и высоту корневого <svg> элемента.
В следующем примере, мы будем использовать внешнее изображение в качестве фона для небольшого линейного графика. Использование фонов может сделать ваш скрипт значительно меньше, потому что мы можем избежать необходимости писать код для создания фона. В этом примере мы используем только один образ, поэтому я использую обработчик событий изображения объекта загрузки для выполнения операторов рисования. drawImage() метод определяющий место фона с координатами (0, 0), которые привязаны к верхнему левому углу canvas.
Получившийся график выглядит так:
Второй вариант метода drawImage() добавляет два новых параметра и позволяет разместить изображение в canvas с изменёнными размерами.
drawImage(image, x, y, width, height)Это добавляет параметр ширины и высоты, которые указывают до какого размера нужно изменить изображение при рисовании его в canvas.
В этом примере, мы будем использовать изображение в качестве обоев и повторим его в canvas несколько раз. Это может быть сделано просто через цикл, располагая изменённые изображения на разных позициях. В коде внизу, первый цикл for проходит по рядам. Второй цикл for проходит по колонкам. Изображение уменьшено на треть от реального размера, которое было 50x38 пикселей.
Примечание: Изображения могут стать размытыми, при большом увеличении или зернистыми при значительном уменьшении. Возможно, лучше всего не изменять размеры изображения, если на них есть текст, который должен остаться читаемым.
Получившийся рисунок canvas выглядит так:
У третьего и последнего варианта метода drawImage() в дополнении к источнику изображения есть ещё восемь параметров . Он позволяет нам вырезать кусок из изображения, затем изменить его размер и нарисовать его в canvas.
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)В данном изображении, эта функция берёт фрагмент из изображения, в виде прямоугольника, левый верхний угол которого - (sx, sy), ширина и высота - sWidth и sHeight и рисует в canvas, располагая его в точке (dx, dy) и изменяя его размер на указанные величины в dWidth и dHeight.
Чтобы понять что делает нарезка, можно посмотреть на изображение справа. Первые четыре параметра определяют местоположение и размер фрагмента исходного изображения. Последние четыре параметра определяют прямоугольник, в который будет вписано изображение на целевом рисунке canvas.
Нарезка может быть полезным инструментом, когда вы захотите сделать композицию. Вы могли бы собрать все элементы в одном файле изображения и использовать этот метод для создания композиции. Например, если вы захотите сделать график, вы могли бы сделать PNG изображение, содержащее все необходимые тексты в одном файле и в зависимости от ваших данных, могли бы достаточно просто изменять график. Другим преимуществом является то, что нет необходимости загружать каждое изображение по отдельности, получив возможность увеличить скорость загрузки.
В этом примере, мы будем использовать того же носорога, что и в предыдущем примере, но мы отрежем его голову и включим её в рамку. Изображение рамки это 24-х битный PNG, который включает падающую тень. Так как в 24-х битные PNG изображения включается полный 8-ми битный альфа-канал, в отличие от GIF и 8-битных PNG изображений, он может быть помещён в любой фон, без беспокойства о матовом цвете.
В этот раз мы применили другой способ загрузки изображения. Вместо загрузки методом создания новых HTMLImageElement объектов, мы включили их как <img> тэги прямо в наш HTML файл и из них выбрали изображения. Изображения скрыты с помощью CSS-свойства display, установленного в "none" для этих изображений.
Скрипт, сам по себе, очень простой. Каждому <img> присвоен атрибут ID, который делает удобным их выбор с использованием document.getElementById(). Потом мы просто используем функцию drawImage(), чтобы из первого изображения вырезать фрагмент носорога и вставить его в canvas, затем рисуем рамку сверху, используя второй вызов функции drawImage().
В последнем примере этой главы, мы построим небольшую галерею искусств. Галерея состоит из таблицы, включающей несколько изображений. Когда страница загрузится, <canvas> элемент вставится в каждое изображение, а вокруг будет нарисована рамка.
В этом случае, у каждого изображения фиксированная ширина и высота, такая же, как и у рамки нарисованной вокруг них. Вы могли бы усовершенствовать этот скрипт так, чтобы он использовал ширину и высоту изображения, чтобы рамка идеально его окружила.
Код ниже должен говорить сам за себя. Мы проходим циклом через document.images контейнер и соответственно добавляем новые элементы canvas. Возможно следует упомянуть для тех, кто не слишком хорошо знаком с DOM, что для этого используется Node.insertBefore метод. insertBefore() это метод родительского узла (ячейки таблицы) элемента (изображения) перед которым мы хотим вставить наш новый узел (элемент canvas).
И сюда какую-нибудь CSS для украшения:
Связывая все вместе JavaScript рисует наши изображения в рамках:
Как было отмечено ранее, изменение размеров изображений может привести к размытости или к шуму в процессе преобразования. Вы можете использовать контекст рисования imageSmoothingEnabled свойства, чтобы контролировать использование сглаживающего алгоритма, когда изменяющиеся изображения в вашем контексте. Обычно это свойство установлено в true, означая, что изображения будут сглажены во время изменения размеров. Вы можете отключить это свойство так:
This page was last modified on 15 апр. 2025 г. by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.