HTML5 Canvas 导出高质量图像教程

如何从画布导出高质量图像?

如果你需要将画布导出为图像或作为 base64,你可以使用 stage.toDataURL()stage.toImage() 方法。

Konva 中,默认情况下导出的图像的 pixelRatio 属性设置为 1。这意味着,如果你导出一个大小为 500x500 的画布,则导出的图像的大小也将为 500x500

在某些情况下,你可能希望导出一个更适合更高(或更小)分辨率的图像。例如,你可能希望将某些内容导出为图像,然后在 HDPI 设备(具有高像素比率的设备,如视网膜显示屏)上的画布中使用该图像。另一个场景可能是你需要在运行高分辨率的计算机上导出用户的绘画。

如果你使用默认设置进行此操作,则你会看到模糊的图像。你可以在这里阅读更多关于全局 pixelRatio 属性的内容 MDN - devicePixelRatio

对于这两种使用情况,你可以使用:

stage.toDataURL({
pixelRatio: 2 // 或你需要的其他值
})

现在,大小为 500x500 的画布将导出为大小为 1000x1000 的图像。Konva 中几乎所有节点都以矢量数据存储,除了位图图像和缓存节点。这导致导出的图像具有高质量。

使用:尝试将画布保存为图像。你会发现它具有高分辨率。

Konva 像素比演示view raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/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);

// 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>