W3docs

Images sur le Canvas

Apprenez à dessiner des images sur un canvas HTML : source d'image, trois formes de drawImage(), gestion du CORS et canvas corrompu.

L'une des fonctionnalités de l'élément <canvas> est la possibilité d'utiliser des images. Celles-ci peuvent servir à différents usages. Vous pouvez utiliser des images externes dans n'importe quel format pris en charge par le navigateur (par ex. PNG, GIF ou JPEG). Comme source, vous pouvez également utiliser l'image créée par d'autres éléments canvas.

Ce chapitre s'appuie sur les bases présentées dans Introduction au Canvas et Dessin sur Canvas. Vous apprendrez ici comment obtenir une source d'image, comment utiliser les trois formes de la méthode drawImage(), et comment éviter le problème du « canvas corrompu » lors du chargement d'images provenant d'autres domaines.

L'importation d'images dans un canvas est un processus en deux étapes :

  1. Obtenir une référence à un autre élément canvas ou à un objet HTMLImageElement en tant que source.
  2. Dessiner une image sur le canvas avec la fonction drawImage().

En tant que source d'image, l'API canvas peut utiliser l'un des types de données suivants :

Type de donnéesDescription
HTMLImageElementCe sont des images créées avec le constructeur Image(), ou tout élément <img>.
SVGImageElementCe sont des images intégrées avec l'élément <image>.
HTMLVideoElementUn élément HTML <video> utilisé comme source d'image extrait la trame actuelle de la vidéo et l'utilise comme image.
HTMLCanvasElementEn tant que source d'image, vous pouvez utiliser un autre élément <canvas>.

Ces sources sont collectivement désignées par le type CanvasImageSource.

Il existe de nombreuses façons d'obtenir des images à utiliser sur un canvas.

Utiliser des images de la même page

Vous pouvez obtenir une référence aux images présentes sur la même page que le canvas avec l'une des méthodes suivantes :

  • La collection document.images
  • La méthode document.getElementsByTagName()
  • La méthode document.getElementById() si vous connaissez l'identifiant de l'image que vous souhaitez utiliser

Par exemple, pour récupérer un élément <img> existant par son identifiant et le dessiner une fois la page chargée :

<img id="photo" src="myImage.png" alt="My image" />
<canvas id="exampleCanvas" width="240" height="225"></canvas>
<script>
  window.onload = function () {
    const canvas = document.getElementById("exampleCanvas");
    const ctx = canvas.getContext("2d");
    const img = document.getElementById("photo");
    ctx.drawImage(img, 0, 0);
  };
</script>

Comme le <img> est déjà présent dans le document, le navigateur a généralement fini de le charger au moment où window.onload se déclenche, il est donc sûr de le dessiner immédiatement.

Utiliser des images provenant d'autres domaines

En utilisant l'élément <img> avec l'attribut crossorigin="anonymous", vous pouvez demander l'autorisation de charger une image depuis un autre domaine. Si le domaine hébergeant l'image autorise l'accès inter-domaines via les en-têtes CORS, vous pouvez utiliser l'image dans votre canvas sans le corrompre.

<img id="remote" src="https://example.com/photo.jpg" crossorigin="anonymous" alt="Remote image" />

Lorsque vous définissez crossorigin="anonymous", le navigateur envoie la requête sans identifiants (cookies). L'image n'est autorisée sur un canvas propre que si le serveur répond avec l'en-tête :

Access-Control-Allow-Origin: *

(ou une valeur qui inclut votre origine). Si vous créez l'image en JavaScript, définissez la propriété avant le src :

const img = new Image();
img.crossOrigin = "anonymous";
img.onload = function () {
  ctx.drawImage(img, 0, 0);
};
img.src = "https://example.com/photo.jpg";

Remarque Si vous dessinez une image d'origine croisée sans configuration CORS appropriée, le canvas devient « corrompu ». Un canvas corrompu bloque l'accès à ses données de pixels pour des raisons de sécurité — appeler toDataURL(), toBlob(), ou getImageData() déclenchera une SecurityError. La solution se trouve côté serveur : il doit envoyer l'en-tête Access-Control-Allow-Origin. Il n'existe aucun moyen de lire les pixels d'un canvas corrompu côté client.

Utiliser d'autres éléments canvas

D'autres éléments canvas sont accessibles via la méthode document.getElementById() ou document.getElementsByTagName().

Intégrer une image via une URL data:

Les URL de données permettent de spécifier une image sous forme de chaîne de caractères encodée en Base64 directement dans le code. L'avantage des URL de données est que l'image résultante est disponible immédiatement. Il est également possible de regrouper l'ensemble de vos fichiers CSS, HTML, JavaScript et images dans un seul fichier.

Cependant, il existe également un inconvénient : l'image n'est pas mise en cache, et l'URL encodée peut être trop longue pour les images de grande taille.

Pour utiliser une URL de données, assignez-la au src d'une image et dessinez-la une fois chargée :

const img = new Image();
img.onload = function () {
  ctx.drawImage(img, 0, 0);
};
img.src =
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==";

La chaîne après base64, est l'image encodée. Comme elle fait partie du script, aucune requête réseau supplémentaire n'est effectuée — l'image est prête dès qu'elle est décodée.

Créer une image de toutes pièces

Vous pouvez également créer un nouvel objet HTMLImageElement dans votre script. Pour cela, utilisez le constructeur Image() :

Créer une image de toutes pièces

const img = new Image();
img.onload = function () {
  ctx.drawImage(img, 0, 0);
};
img.src = "myImage.png";

Le chargement de l'image commence au moment où src est défini, et ce chargement est asynchrone. Si vous appelez drawImage() avant que l'image ait fini de se charger, rien n'est dessiné. Pour vous assurer que drawImage() ne s'exécute qu'une fois l'image prête, attachez le gestionnaire d'événement onload avant de définir src.

La fonction drawImage()

Une fois qu'une référence à l'image source est disponible, vous pouvez utiliser la méthode drawImage(). Elle se présente sous trois formes, chacune acceptant davantage de paramètres que la précédente :

1. Position seulement

ctx.drawImage(image, dx, dy);

Dessine l'image entière à sa taille naturelle, en plaçant son coin supérieur gauche au point (dx, dy) sur le canvas.

2. Position et taille (mise à l'échelle)

ctx.drawImage(image, dx, dy, dWidth, dHeight);

Dessine l'image entière, mise à l'échelle pour s'adapter à une zone de dWidth × dHeight pixels dont le coin supérieur gauche est à (dx, dy).

3. Découpage (rectangle source vers rectangle destination)

ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

Extrait une portion rectangulaire de l'image source et la dessine dans un rectangle de destination sur le canvas. C'est la forme la plus flexible — elle est utilisée pour les feuilles de sprites, le recadrage et le zoom.

Les paramètres se divisent en deux groupes :

ParamètreGroupeSignification
sx, sySourceCoin supérieur gauche de la portion découpée dans l'image source.
sWidth, sHeightSourceLargeur et hauteur de cette portion.
dx, dyDestinationEmplacement où la portion est placée sur le canvas.
dWidth, dHeightDestinationTaille à laquelle la portion est dessinée sur le canvas (mise à l'échelle si différente de sWidth/sHeight).

Les valeurs s* (source) sont mesurées en pixels de l'image originale ; les valeurs d* (destination) sont mesurées en pixels du canvas. La forme de base, drawImage(image, dx, dy), est simplement la première de ces trois formes.

Dans l'exemple suivant, nous utilisons la méthode document.getElementById() pour obtenir une référence à l'image, puis nous utilisons la fonction drawImage() pour la dessiner.

Exemple de dessin d'une image avec la fonction drawImage() :

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>Image</h2>
    <img id="photo" src="/uploads/media/default/0001/01/25acddb3da54207bc6beb5838f65f022feaa81d7.jpeg" alt="Aleq" width="200" height="185" />
    <h2>Image with canvas:</h2>
    <canvas id="exampleCanvas" width="240" height="225" style="border:2px solid #cccccc;">
      Your browser doesn't support the canvas tag.
    </canvas>
    <script>
      window.onload = function() {
        const canvas = document.getElementById("exampleCanvas");
        const ctx = canvas.getContext("2d");
        const img = document.getElementById("photo");
        ctx.drawImage(img, 20, 20);
      };
    </script>
  </body>
</html>
Danger

Les images SVG doivent définir la largeur et la hauteur dans l'élément racine <svg>.

Utiliser des trames d'une vidéo

Il est également possible d'utiliser des trames d'une vidéo présentée par un élément <video>, même lorsque la vidéo n'est pas visible. Par exemple, si vous avez un élément <video> avec l'identifiant "videoCanvas", procédez comme suit :

Exemple de dessin d'une vidéo avec canvas :

Images Canvas

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <h2>Video</h2>
    <video id="videoCanvas" controls width="350" autoplay>
      <source src="/build/videos/arcnet.io(7-sec).mp4" type="video/mp4" />
    </video>
    <h2>Canvas  draws the current video:</h2>
    <canvas id="exampleCanvas" width="310" height="190" style="border:1px solid #d3d3d3;">
      Your browser doesn't support the canvas tag.
    </canvas>
    <script>
      const v = document.getElementById("videoCanvas");
      const c = document.getElementById("exampleCanvas");
      const ctx = c.getContext("2d");
      let animId;
      function drawFrame() {
        ctx.drawImage(v, 5, 5, 300, 180);
        animId = requestAnimationFrame(drawFrame);
      }
      v.addEventListener("play", function() {
        animId = requestAnimationFrame(drawFrame);
      }, false);
      v.addEventListener("pause", function() {
        cancelAnimationFrame(animId);
      }, false);
      v.addEventListener("ended", function() {
        cancelAnimationFrame(animId);
      }, false);
    </script>
  </body>
</html>

Pratique

Pratique
Lorsque vous créez une image en JavaScript pour la dessiner sur le canvas, quel est l'ordre correct des étapes ?
Lorsque vous créez une image en JavaScript pour la dessiner sur le canvas, quel est l'ordre correct des étapes ?
Was this page helpful?