与 img 标签相比,drawImage 生成的质量较差 [英] drawImage generates bad quality compared to img tag

查看:21
本文介绍了与 img 标签相比,drawImage 生成的质量较差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用 drawImage 将图像放在画布上时,它看起来总是不如使用标签的相同图像那么清晰.我搜索了很多解决方案,例如下采样、smoothingEnabled,但都没有帮助.如何提高drawImage的质量?

When I use drawImage to put an image on canvas, it always looks not as sharp as the same image using a tag. I have searched for many solutions, for example, downsampling, smoothingEnabled, but none is helping. How to improve quality of 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>

推荐答案

您似乎在视网膜式显示器上.这可以通过查看屏幕截图的大小(2264 × 886)来确认.

You seem to be on a retina-like display. This can be confirmed by looking at the size of your screenshot (2264 × 886).

这些显示器确实具有更高的像素密度.为了使网页的大小与作者的意图保持一致,他们会自动放大页面的所有内容.

These displays do have an higher pixel density. To keep the sizes of web-pages consistent with what the author intended, they do up-scale automatically all the content of the page.

这意味着您的 标签实际上是以 1100x810px 绘制的,您的画布也是如此.
但是,这种自动化仅在表示级别 (CSS) 上完成.您的画布上下文仍然只包含 550x405 像素.因此,当在表示级别通过时,它必须通过 CSS 对其进行升级,这会导致质量下降.

This means that your <img> tag is actually drawn at 1100x810px, so is your canvas.
However, this automation is only done at a presentation level (CSS). Your canvas context still contains only 550x405 pixels. So when passed at presentation level, it has to upscale it, via CSS, which produces this loss of quality.

没有万无一失的方法可以知道屏幕的 PPI(每英寸像素数)比率,但由于 window.devicePixelRatio 属性.如果您的用户经常使用浏览器的缩放级别,这可能不准确,但在 90% 的情况下,它可以正常工作.

There is no bullet-proof method to know the PPI (Pixels Per Inch) ratio of a screen, but you can still try to get it thanks to the window.devicePixelRatio property. This may be inaccurate if your user does play a lot with its browser's zoom level, but in 90% of cases, it works fine.

一旦你有了这个,你可以手动为画布做浏览器所做的事情 :放大其内容并缩小其显示.

Once you've got this, you can do manually for the canvas what the browser does for the <img> : upscale its content and downscale its presentation.

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>

这篇关于与 img 标签相比,drawImage 生成的质量较差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆