Javascript drawImage not drawing anything inside canvas

85 Views Asked by At

I have the below JS code. It's supposed to take the contents of a canvas, resize them and then save them as an image.

saveImg.addEventListener("click", () => {
  var img1 = new Image();
  img1.src = canvas.toDataURL();

  const link = document.createElement("a"); // Se creează un element HTML <a> (link) și se stochează în variabila "link".

  function resizeImage(img1, w, h) {
    var result = new Image();
    var aux_canvas = document.createElement("canvas");
    aux_canvas.width = w;
    aux_canvas.height = h;
    console.log(aux_canvas);
    aux_ctx = aux_canvas.getContext("2d");
    if (img1.complete) {
      console.log("complete");
      aux_ctx.drawImage(img1, 0, 0, w, h);
    } else {
      console.log("!complete");
      img1.onload = function () {
        console.log("onload");
        aux_ctx.drawImage(img1, 0, 0, w, h);
      };
    }
    console.log(img1);
    //aux_canvas.getContext("2d").drawImage(img_func, 0, 0, w, h);
    result.src = aux_canvas.toDataURL();
    return result;
  }

  var img2 = resizeImage(img1, 28, 28);

  link.download = `${Date.now()}.jpg`; //se setează proprietatea "download" a elementului link. Această proprietate specifică numele fișierului pentru descărcare. În acest caz, se utilizează valoarea Date.now() care este timpul curent exprimat ca număr de milisecunde de la 1 ianuarie 1970. Această valoare este concatenată cu ".jpg" pentru a crea un nume unic pentru fișierul de imagine.
  link.href = img2.src; //Se setează proprietatea "href" a elementului link. Această proprietate specifică locația fișierului sau a resursei asociate cu linkul. În acest caz, se utilizează metoda "toDataURL()" a elementului "canvas" pentru a obține o reprezentare sub formă de imagine a conținutului din elementul canvas. Această reprezentare este stocată sub formă de URL de date, care este apoi atribuit la proprietatea "href" a elementului link.
  link.click(); // clicking link to download image
});

The function drawImage doesn't seem to be doing anything, even though img1 contains the data from the canvas. Any suggestions on how I could fix this?

Thanks in advance!

Tried manually drawing a rectangle using drawRect inside aux_canvas and that one saves fine.

1

There are 1 best solutions below

0
James On

Assuming the image hasn't loaded when the click() happens, you can try this. I took the img.onload part and wrapped it in a promise, which is awaited. I'm not sure if the Stack Overflow snippet tool will allow the auto-download part (I see "Download is disallowed. The frame initiating or instantiating the download is sandboxed" in the console), but the same code works as expected on jsFiddle

let saveImg = document.querySelector("button");
let canvas = document.querySelector("canvas");
// draw something for demo purposes
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 100, 100);


async function drawImageOnCanvas(img, context, w, h) {
  if (img.complete) {
    console.log("complete");
    context.drawImage(img, 0, 0, w, h);
    return Promise.resolve();
  } else {
    return new Promise(resolve => {
      img.onload = function () {
        console.log("onload");
        context.drawImage(img, 0, 0, w, h);
        resolve();
      };
    });
  }
}

saveImg.addEventListener("click", async () => {
  var img1 = new Image();
  img1.src = canvas.toDataURL();

  async function resizeImage(img1, w, h) {
    var result = new Image();
    var aux_canvas = document.createElement("canvas");
    aux_canvas.width = w;
    aux_canvas.height = h;
    aux_ctx = aux_canvas.getContext("2d");
    await drawImageOnCanvas(img1, aux_ctx, w, h);
    result.src = aux_canvas.toDataURL();
    return result;
  }

  var img2 = await resizeImage(img1, 28, 28);
  
  const link = document.createElement("a");
  link.download = `${Date.now()}.jpg`;
  link.href = img2.src;
  link.click();
});
<canvas height="200" width="200"></canvas>
<button>Save</button>