<div class="example photos">
  <p>Click the image to copy.</p>
  <p>
    JPG (writes to canvas to force into PNG format first):<br>
    <img src="https://assets.codepen.io/74045/house.jpg" alt="a house" title="click to copy" />
  </p>
  <p>
    PNG:<br />
    <img src="https://assets.codepen.io/74045/house.png" alt="a house" title="click to copy" />
  </p>

  <p>If this doesn't work for you <a href="https://codepen.io/pen/debug/dyBeGeg" target="_blank">try Debug Mode</a>.</p>
</div>
body {
  height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
  background: #455a64;
  font-family: monospace;
}

.example {
  background: white;
  border-radius: 12px;
  overflow: clip;
  width: 75dvi;
}

p {
  text-align: center;
  padding-inline: 1rem;
}
let imgs = document.querySelectorAll("div.photos img");
imgs.forEach((i) => {
  i.addEventListener("click", copyImagetoCB);
});

async function copyImagetoCB(e) {
  let type = e.target.src.split(".").pop();
  let blob;
  console.log("type", type);

  // support JPG/PNG only
  if (type === "jpg" || type === "jpeg") {
    blob = await setCanvasImage(e.target.src);
  } else if (type.endsWith("png")) {
    let dataReq = await fetch(e.target.src);
    let data = await dataReq.blob();

    blob = new Blob([data], { type: "image/png" });
  }

  let cbData = [new ClipboardItem({ "image/png": blob })];
  await navigator.clipboard.write(cbData);
  console.log("Done");
}

async function setCanvasImage(path) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.crossOrigin = "anonymous";
    const c = document.createElement("canvas");
    const ctx = c.getContext("2d");

    img.onload = function () {
      c.width = this.naturalWidth;
      c.height = this.naturalHeight;
      ctx.drawImage(this, 0, 0);
      c.toBlob((blob) => {
        resolve(blob);
      }, "image/png");
    };
    img.src = path;
  });
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.