Cara menyalin gambar

Banyak browser modern mendukung penyalinan gambar ke papan klip dalam format PNG dan SVG. Format lain belum didukung karena alasan keamanan.

Cara modern

Menggunakan Async Clipboard API

Metode Clipboard.write() mengambil array objek ClipboardItem dan menampilkan Promise yang di-resolve saat gambar berhasil ditulis ke papan klip. Clipboard.write() hanya dapat digunakan dari objek window yang memiliki fokus.

Browser Support

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 127.
  • Safari: 13.1.

Source

Cara klasik

Menggunakan navigator.clipboard.writeText()

Meskipun tidak semua browser mendukung navigator.clipboard.write() untuk data biner, semuanya mendukung navigator.clipboard.writeText(). Jika ingin menyalin gambar SVG, Anda dapat menyalin kode sumber SVG, bukan menyalin gambar itu sendiri. Sayangnya, Anda tidak dapat menyalin gambar PNG.

Browser Support

  • Chrome: 66.
  • Edge: 79.
  • Firefox: 63.
  • Safari: 13.1.

Source

Progressive enhancement

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

Bacaan lebih lanjut

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