与img标签相比,drawImage产生的质量很差

时间:2017-01-08 00:20:29

标签: html html5 image canvas

当我使用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>

You can clearly the difference in their quality

1 个答案:

答案 0 :(得分:3)

您似乎处于类视网膜显示屏上。这可以通过查看屏幕截图的大小(2264×886)来确认。

这些显示器的像素密度更高。为了使网页的大小与作者的意图保持一致,他们会自动向上扩展页面的所有内容。

这意味着您的<img>代码实际上是以1100x810px绘制的,画布也是如此。
但是,此自动化仅在表示级别(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';
<img width="550" height="405" src="https://i.stack.imgur.com/s15bD.png" />
<canvas id="image"></canvas>