Come copiare le immagini

Thomas Steiner
Thomas Steiner

Molti browser moderni supportano la copia delle immagini negli appunti nei formati PNG e SVG. Per motivi di sicurezza, gli altri formati non sono ancora supportati.

Il modo moderno

Utilizzo dell'API Async Clipboard

Il metodo Clipboard.write() prende un array di oggetti ClipboardItem e restituisce una Promessa che si risolve quando l'immagine viene scritta correttamente negli appunti. Clipboard.write() può essere utilizzato solo dall'oggetto window impostato come attivo.

Supporto del browser

  • 66
  • 79
  • 13.1

Fonte

Il classico

In uso: navigator.clipboard.writeText()

Sebbene non tutti i browser supportino ancora navigator.clipboard.write() per i dati binari, supportano tutti navigator.clipboard.writeText(). Se vuoi copiare un'immagine SVG, invece di copiare l'immagine stessa, puoi copiare il codice sorgente SVG. Sfortunatamente, per le immagini PNG sei sfortunato.

Supporto del browser

  • 66
  • 79
  • 63
  • 13.1

Fonte

Miglioramento progressivo

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);
  }
});

Per approfondire

Demo

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);
  }
});