当我使用 drawImage 将图像放在画布上时,它看起来总是不如使用标签的相同图像那么清晰。我已经搜索了许多解决方案,例如下采样、smoothingEnabled,但都没有帮助。如何提高drawImage的质量?
<html>
<head>
</head>
<body>
<img src="test.png" width="550" height="405">
<canvas id="image"></canvas>
</body>
<script type="text/javascript">
var canvas = document.getElementById('image');
var ctx = canvas.getContext('2d');
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
canvas.width = 550;
canvas.height = 405;
canvas.style.width = canvas.width.toString() + "px";
canvas.style.height = canvas.height.toString() + "px";
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = 'test.png';
</script>
Run Code Online (Sandbox Code Playgroud)
你似乎在一个类似视网膜的显示器上。这可以通过查看屏幕截图的大小 (2264?×?886) 来确认。
这些显示器确实具有更高的像素密度。为了使网页的大小与作者的意图保持一致,他们会自动放大页面的所有内容。
这意味着您的<img>标签实际上是以 1100x810 像素绘制的,您的画布也是如此。
但是,这种自动化仅在表示级别 (CSS) 上完成。您的画布上下文仍然只包含 550x405 像素。因此,当在表示级别通过时,它必须通过 CSS 对其进行升级,这会导致质量下降。
没有防弹方法可以知道屏幕的 PPI(每英寸像素数)比率,但由于该window.devicePixelRatio属性,您仍然可以尝试获得它。如果您的用户经常使用浏览器的缩放级别,这可能不准确,但在 90% 的情况下,它可以正常工作。
一旦你有了这个,你可以手动为画布做浏览器为<img>它做的事情:放大它的内容并缩小它的展示。
var canvas = document.getElementById('image');
var ctx = canvas.getContext('2d');
// upscale the canvas content
canvas.width = 550 * devicePixelRatio;
canvas.height = 405 * devicePixelRatio;
// downscale the presentation
canvas.style.width = (canvas.width / devicePixelRatio).toString() + "px";
canvas.style.height = (canvas.height / devicePixelRatio).toString() + "px";
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = 'https://i.stack.imgur.com/s15bD.png';Run Code Online (Sandbox Code Playgroud)
<img width="550" height="405" src="https://i.stack.imgur.com/s15bD.png" />
<canvas id="image"></canvas>Run Code Online (Sandbox Code Playgroud)