What is the best practice to export canvas with high quality images?

ptCoder picture ptCoder · Jun 10, 2013 · Viewed 19.5k times · Source

I need your help. I explain my situation: I’m using fabric.js library to place shapes, text, etc. in my application. My canvas size has 1000x1000 pixels (about 26.45x26.45 centimeters). I have an image upload script only for upload images in high quality, like 300 dpi.

Basically what I do is the following: - draw the canvas (uploading images, put text, etc…); - resize the canvas multiplying by scale factor to be able at the end to have an image with 300dpi; - save the canvas in PNG format; - using php/ajax and Imagick, put the canvas with 300 dpi quality, saving in jpg format.

The problem is: when I save the canvas, the quality of uploaded images will decrees, because I resize the canvas was 72 dpi (at the moment that I save in PNG).

I think a possible solution is: when uploading the images, save the position in an array with x and y position and size to the end of the whole process, replace the image in JPG. If this is a best way, it is possible to make it with Imagick library or in PHP?

I would like to know your opinion about it.

Thank You.

Answer

user1693593 picture user1693593 · Jun 11, 2013

The DPI doesn't matter at all when dealing with images. Images are measured in pixels so this is what you need to adjust. You can safely disregard DPI as it has no sense in this context.

Scaling won't help you here - remember you are working with a pixel device, not vectors, so the canvas need to be already in the size you want to use for print etc. or you will have reduced quality due to interpolation when scaling it.

Here's how:

You need to pre-calulate your canvas size in pixels in relation to what size you want in the final stage.

Lets say you want to print a 15 x 10 cm image (or about 6 x 4 inches) @ 300DPI output. You then calculate the pixels:

Width : 10 cm * 300 / 2.54 = 1181 pixels
Height: 15 cm * 300 / 2.54 = 1772 pixels

For inches simply multiply with the DPI (4 in != 10 cm so a little different result, numbers picked for simplicity):

Width : 4 in * 300 = 1200 pixels
Height: 6 in * 300 = 1800 pixels

For your image at 26.45 cm @ 300 DPI the canvas would need to be:

26.45 cm * 300 DPI / 2.54 inches = 3124 pixels.

To display that canvas in a smaller area on screen you use CSS to display the element, for example -

<canvas width="3124" height="3124" style="width:600px;height:600px;"></canvas>

You can now draw to the canvas at its actual pixel position and it will show up scaled down on screen (but retain all information on the canvas itself). If you use mouse coordinates you just scale the mouse position proportionally (canvas pos = mouse coord * 3124px / 600px).

For zooming etc it becomes a tad more complicated, but the principle remains: the final size of your image must be that of the final result.

About DPI: if this image was 72 DPI or 300 DPI the numbers of pixels would be the exact same. The reason as already mentioned is that images are measured in pixels.

DPI is an arbitrary value when it comes to pixel devices (bitmaps, monitors, cameras etc.) and is only used for a DTP software to get a hint on dimension for final print which will use this information only to pre-scale the image in relation to the page you using to set the print with.