user115202 user115202 - 3 years ago 300
Javascript Question

canvas.toDataURL() does not alter image quality. How comes?

According to the docs:

The HTMLCanvasElement.toDataURL() method returns a data URI containing
a representation of the image in the format specified by the type
parameter (defaults to PNG). The returned image is in a resolution of
96 dpi

How is it possible to refer to a print resolution when there is no printing involved?

I've written a jsfiddle that draws an image on a canvas, then calls toDataURL(). It seems that the quality of the resulting image is not affected, after all.

I can't understand what does 96 dpi mean in the docs. Any thoughts?

var image = new Image();
image.crossOrigin = "Anonymous";
image.src = "...";
// ...
var dataURL = canvas.toDataURL('image/jpeg', 1.0);;

Answer Source

How is it possible to refer to a print resolution when there is no printing involved?

The quote from MDN is wrong in the sense it refers to DPI as resolution for the image.

(Side note: PPI vs DPI differs in physical properties - but not really important in this context. You'll see me using DPI for PPI as it has been so ingrained since I started using it in the early 90s).

The (somewhat) short answer to your question would be:

Images are only measured in pixels and has no concept of real-world sizes. DPI is purely arbitrarily when saved as meta in/with images and function as a hint when transferred to physical medium such as a screen or to paper (and the entire pipe-line displaying the image considers its DPI).

As to why: The 96 DPI refers to the "standard" (but inaccurate and a bit outdated) screen pixel density so that if you do print your image to paper as-is and hold the paper up against your screen the content on paper should somewhat match in size with that you see on the screen (most people don't calibrate theirs screens for actual DPI, and manufacturers are sometimes sloppy with their drivers, if not a generic driver is used, so there will be a small error margin).

The browser doesn't actually store this information in the image files it produces either (not that it need to, see below).

And just to document, lets first look at the binaries of a JPEG file:

hexdump of jpeg from firefox
Hex-dump of JPEG saved from Firefox, but the case is the same for Chrome.

Nope, no unit defined (0) at position 0x0D. This must be either 1 (inch) or 2 (cm) (and of course no EXIF (0xffe1/APP1) as there is no camera/scanner producing the image).

How about PNG then?

hexdump from Firefox
Hex-dump of PNG saved from Firefox, but the case is the same for Chrome.

Nope, neither here. No pHYs chunk and IHDR only contains actual pixel resolution.

And that's OK as an image is assumed to be 96 DPI on most systems nowadays so it doesn't have any consequences (where DPI is actually used to affect the image, and no other DPI/PPI is defined).

For you and me in most cases though, a 1920x1080 image will be 1920x1080 on a 15" as well as on a 50" screen. Just ignore...

So in conclusion: When you pass the image through the canvas the image may have a hint embedded that indicates for example 300 DPI. This is stripped off of course when saving out canvas, but it does not alter the image resolution (provided the canvas is of the same pixel resolution as the original image) so there will be no drop in print quality (compression via JPEG can of course affect general quality, but for actual resolution there is no change).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download