What Is the Best Practice to Export Canvas with High Quality Images

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

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.

Draw Image on Canvas and export print quality image

You should not style canvas directly with dimensions.
Set the canvas attribute width and height, without exceeding the screen dimensions:

<canvas width="500" height="400" ></canvas>

When exporting to image use

canvas.toDataURL({multiplier: 4});

This will give you a canvas 4 times bigger the one on the screen.

Styling the canvas with the style to reduce its diemension and having a bigger image with dataURL will make the overall experience worse.

The style squeeze the canvas to your eyes with something that fabricjs is not ready to understand. So you will not get normal sized controls.

//remove those
width:400px !important;
height:600px !important;

http://jsfiddle.net/Q3TMA/1043/

How to get a high quality canvas to PNG conversion

You can decide the proper size for the canvas and then modify the way it's displayed via CSS. Here, the final size is set as 2000x2000 and it will be saved as such (by clicking on it), regardless of the viewport size:

const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');
// Draw the ellipsectx.beginPath();ctx.lineWidth = 10;ctx.ellipse(1000, 1000, 500, 800, Math.PI / 4, 0, 2 * Math.PI);ctx.stroke();
// Draw the ellipse's line of reflectionctx.beginPath();ctx.setLineDash([5, 5]);ctx.moveTo(0, 2000);ctx.lineTo(2000, 0);ctx.stroke();

canvas.addEventListener('click', function (e) { var dataURL = canvas.toDataURL('image/png'); var link = document.createElement("a"); link.download = "finalsize.png"; link.href = dataURL; link.click();});
<body style="display:flexbox"> <canvas id="canvas" width="2000" height="2000" style="width:100%; "></canvas></body>

Canvas Content as High Resolution Image.

The best way to achieve this is to resize stage before export, then resize it back:

var oldSize = stage.size();

var exportSize = {
width: 3000,
height: 3000
};
stage.size(exportSize);
stage.draw();
var dataURL = stage.toDataURL(exportSize);
stage.size(oldSize);
stage.draw();

Demo: http://plnkr.co/edit/DiqsE7rZdDx3JIAyJZQK?p=preview

Export image from canvas in printing size (300 DPI)

If you have smaller canvas elements for editing, then you will have to recombine the data from those smaller canvas elements into a canvas element which is the full size and output the data from that element.

For simplicity's sake, let's say that you have cut the image into four quadrants and drawn to four canvas elements canvas[0] - canvas[3] for editing. You would then need to recombine them into one larger canvas doing something like the following...

var imgData = [];
for (var i = 0; i < 4; i++) {
var tmpCtx = canvas[i].getContext('2d');
imgData[i] = tmpCtx.getImageData(0, 0, canvas[i].width, canvas[i].height);
}

var fullSizeCanvas = document.createElement('canvas');
fullSizeCanvas.width = img.width * 2;
fullSizeCanvas.height = img.height * 2;

var fullCtx = fullSizeCanvas.getContext('2d');
fullCtx.putImageData(imgData[0], 0, 0);
fullCtx.putImageData(imgData[1], img.width, 0);
fullCtx.putImageData(imgData[2], 0, img.height);
fullCtx.putImageData(imgData[3], img.width, img.height);

var data = fullSizeCanvas.toDataURL();


Related Topics



Leave a reply



Submit