HTML5 Canvas Export to Hight Quality Image Tutorial

How to get a better quality of an image on stage export?

If you need to export a stage to image or to base64 you can use stage.toDataURL() or stage.toImage() methods.

By default Konva exports into image with pixelRatio = 1. That means if you export stage with the size 500x500 you will have the image with the same size.

But in some cases you may need an image with better quality or higher resolutions (or smaller). For instance you want to export something into image and then use that image on the canvas on HDPI devices (with high pixel ratio). You can read more about pixelRatio here MDN - devicePixelRatio. If you do this with default settings you will see blurred image. Or you need to export user’s drawing into computer with hight resolution.

To do this you can use this:

stage.toDataURL({
pixelRatio: 2 // or other value you need
})

In that case a stage with the size 500x500 will be exported into 1000x1000 image. Almost all nodes in Konva stored as vector data (expect bitmap images and cached nodes). So you will have image with better quality.

Usage: try to save stage as image. You will see that it have large resolution.

Konva Pixel Ratio Demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva High Quality Export Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}

#buttons {
position: absolute;
top: 5px;
left: 10px;
}

#buttons > input {
padding: 10px;
display: block;
margin-top: 5px;
}
</style>
</head>

<body>
<div id="container"></div>
<div id="buttons"><button id="save">Save as image</button></div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});

var layer = new Konva.Layer();
stage.add(layer);

var box = new Konva.Rect({
x: stage.width() / 2 - 50,
y: stage.height() / 2 - 25,
width: 100,
height: 50,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(box);

var circle = new Konva.Circle({
x: stage.width() - 50,
y: stage.height() - 50,
radius: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(circle);

layer.draw();

// function from https://stackoverflow.com/a/15832662/512042
function downloadURI(uri, name) {
var link = document.createElement('a');
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}

document.getElementById('save').addEventListener(
'click',
function() {
var dataURL = stage.toDataURL({ pixelRatio: 3 });
downloadURI(dataURL, 'stage.png');
},
false
);
</script>
</body>
</html>