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);
window.open(dataURL);
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:
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?
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).
There is indeed a typo in this quote since they should probably have used ppi instead of dpi and IIRC the EXIF tag is called pixel-density, but it's a common one.
The ppi in jpeg format is simply a note for softwares to let them know that your 300px * 300px digital image is intended to be rendered at a size of 1in*1in.
So if the renderer is a printer, able to print at 300dpi, that will do one dot per pixel.
This info is written inside the file's metadata, and whatever the original value set in your original image, toDataURL
will only set the JFIF Density Unit metadata to 0 (no units), and X and Y density to 1 (MDN talks about 96dpi because it corresponds to the most standards screen's display ratio, also used in CSS px
magic unit).