A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

Img#toDataURL() and Img#download() and Element#screenshot()


I’d like the following to be possible:

Let’s say we have reference of an Image:

var img = document.createElement('img');
img.src = "image.png";

I should be able to convert that image to DataURL:

img.toDataURL(); // returns DataURL of that image just like Canvas#toDataURL();

I should be able to download it as well, but not like:

<a download="filename">

Because the file is downloaded when that anchor tag’s click() is called either by API or user gesture.

So for <img> it should be a method: (since we wouldn’t want it to download on click)


Now the screenshot() method on Elements:

Element.screenshot(); // returns an <img> element

This returns a <img> element so that I don’t have to create an <img> element and change the src, it would be done automatically, and now I can easily:

var screenShot = Element.screenshot(); // get <img>
screenShot.download('filename'); // can easily download image
document.body.appendChild(screenShot); // can easily add to DOM

IMO it would be better to have toBlob() instead of toDataURL() since data URLs bloat the data size. My ImageData conversion API proposal already includes a way to do this via ImageData.create(img).toBlob(), or you can use a synchronous draw to canvas then call toBlob() on the canvas.

Similarly you can already download an image by first converting it to a Blob, calling URL.createObjectURL(blob), then downloading that URL.

Screenshotting elements has been discussed before IIRC and has some privacy issues. I think the biggest problem with screenshot() returning is you need to know what to set for the src attribute. Returning a Blob, ImageData or Canvas would probably be more suitable.


That’s kind of the whole point, what your doing is more work.

var a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'filename.png';

or window.open()

compare to:


and creating a canvas just to download a picture.

So instead of dealing with a blob, your dealing with an <img> element which will allow you to easily add to the DOM

Well you did say IMO so I’ll wait for others to respond or please add on.


You could easily write a helper function to do that, and even attach it to HTMLImageElement so your exact example works.


And you could too for your ImageData.create(img) so your point is??


No, you couldn’t - not asynchronously, which is the purpose of the proposal.


Okay and you couldn’t do what I would do asynchronously as well, because that’s all internally, so again your point??


I’m not sure what you mean. I don’t see any problem with downloading an image being a synchronous function.