Comment copier des images

De nombreux navigateurs récents permettent de copier des images dans le presse-papiers aux formats PNG et SVG. Les autres formats ne sont pas encore acceptés pour des raisons de sécurité.

Méthode moderne

Utiliser l'API Async Clipboard

La méthode Clipboard.write() prend un tableau d'objets ClipboardItem et renvoie une promesse qui se résout lorsque l'image est correctement écrite dans le presse-papiers. Clipboard.write() ne peut être utilisé qu'à partir de l'objet window sélectionné.

Navigateurs pris en charge

  • 66
  • 79
  • 13.1

Source

Méthode classique

Utiliser navigator.clipboard.writeText()

Bien que tous les navigateurs ne soient pas encore compatibles avec navigator.clipboard.write() pour les données binaires, ils sont tous compatibles avec navigator.clipboard.writeText(). Si vous souhaitez copier une image SVG, vous pouvez copier le code source SVG au lieu de copier l'image elle-même. Pour les images PNG, vous n'avez malheureusement pas de chance.

Navigateurs pris en charge

  • 66
  • 79
  • 63
  • 13.1

Source

amélioration progressive

const button = document.querySelector('button');
const img = document.querySelector('img');

button.addEventListener('click', async () => {
  const responsePromise = fetch(img.src);
  try {
    if ('write' in navigator.clipboard) {
      await navigator.clipboard.write([
        new ClipboardItem({
          'image/svg+xml': new Promise(async (resolve) => {
            const blob = await responsePromise.then(response => response.blob());
            resolve(blob);
          }),
        }),
      ]);
      // Image copied as image.
    } else {
      const text = await responsePromise.then(response => response.text());
      await navigator.clipboard.writeText(text);
      // Image copied as source code.
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});

Complément d'informations

Démonstration

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎉</text></svg>"
    />
    <title>How to copy images</title>
  </head>
  <body>
    <h1>How to copy images</h1>
    <img src="assets/fugu.svg" alt="Fugu fish." width="128" height="128">
    <button type="button">Copy</button>
  </body>
</html>

CSS


        :root {
  color-scheme: dark light;
}

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

button {
  display: block;
}
        

JS


        const button = document.querySelector('button');
const img = document.querySelector('img');

button.addEventListener('click', async () => {
  const responsePromise = fetch(img.src);

  try {
    if ('write' in navigator.clipboard) {
      await navigator.clipboard.write([
        new ClipboardItem({
          'image/svg+xml': new Promise(async (resolve) => {
            const blob = await responsePromise.then(response => response.blob());
            resolve(blob);
          }),
        }),
      ]);
      // Image copied as image.
    } else {
      const text = await responsePromise.then(response => response.text());
      await navigator.clipboard.writeText(text);
      // Image copied as source code.
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
});