3

The question on a single line:

Is there a toDataURL method working on a <IMG> element?

Most of the people seem to be interested in how to get an IMG from a CANVAS, but I need the opposite.
Why? I need to use the toDataURL() method on the IMG.

So, this is the pseudo code that I wish existed in reality:

var img     = document.getElementById('myImage');
var canvas  = img.getCanvasFromImage();
var dataURL = canvas.toDataURL();

Is there already a method, or a workaround (e.g. creating an empty canvas, copying the IMG on top, etc.) to do the getCanvasFromImage? I couldn't find one.

Some more details WHY, but there is no need to read further.
I am using the VIDEO tag to get the camera stream, and when the user clicks a button, I copy the CANVAS to the IMG.
But since I do not want to show the whole picture while taking a photo (I want it to be consistent over different devices, regardless of the camera resolution, keeping a 16:9 aspect ratio), I only show a portion of the image using object-fit: cover; .
So, now I have a "partial" image, but if I do a toDataURL on the canvas I have, it gives me the WHOLE picture, regardless of the "object-fit" value.
If this is not clear, no problem :) I only need a "toDataURL" method working on a <IMG> element :)

ZioBit
  • 905
  • 10
  • 29

1 Answers1

6

HTMLImageElement.prototype.getCanvasFromImage = function(){
  const canvas = document.createElement('canvas');
  canvas.width = this.width;
  canvas.height = this.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(this, 0, 0);
  return canvas;
};


const img = document.getElementById('myImage');
img.onload = () => {
  const canvas  = img.getCanvasFromImage();
  const dataURL = canvas.toDataURL();

  console.log(dataURL);
}
<img id="myImage" crossorigin="anonymous" src="https://dl.dropbox.com/s/zpoxft30lzrr5mg/20201012_102150.jpg" />

Its work, but please READ THIS. Better way is create pure function and pass image as argument:

function getCanvasFromImage(image) {
   const canvas = document.createElement('canvas');
   canvas.width = image.width;
   canvas.height = image.height;
   const ctx = canvas.getContext('2d');
   ctx.drawImage(image, 0, 0);
   return canvas;
}
Darth
  • 1,592
  • 10
  • 19
  • Thank you for the link too. In reality, I wanted to create a pure function because I had no clue how to use prototype :) Let me try it and I will accept the answer – ZioBit May 06 '21 at 04:05
  • Yes it works and I understand all your code. But now I have a different problem: it looks like the width/height is wrong. The aspect ratio is perfect, but it only captures the upper left corner, almost like if there is a proportional factor between the height/width reported by JS and the "real" pixels on the screen. I am investigating this and I will report my findings – ZioBit May 06 '21 at 04:49
  • @ZioBit You can try https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight – Darth May 06 '21 at 05:25
  • Oh my gosh. I just opened a can of worms. Thank you for your answer. I will learn all about points, dpi, pixels in CSS. – ZioBit May 06 '21 at 05:44