【问题标题】:How to deal with quality loss using canvas drawImage?如何使用画布drawImage处理质量损失?
【发布时间】:2017-09-25 03:56:43
【问题描述】:

我在 Stackoverflow 上看到了这个问题,但我没有找到答案 - 提出的所有解决方案都对我不起作用。

问题:当我将 base64 编码的 SVG 作为 src 传递给图像时,它看起来与原始 SVG 图像一样清晰。但是,如果我将这张图片用在画布中(通过 context.drawImage)——它的质量会更差:

问题是 - 如何在画布中绘制看起来像原始图像的基于 svg 的图像?

到目前为止我尝试了什么。 here(重新迭代下采样)描述的方法对我不起作用。另一个advise(给尺寸增加0.5)也没有保存这种情况。与imageSmoothingEnabled 一起玩 - 仍然没有运气。

这是用于生成此特定屏幕截图的the codepen

let toBase64 = (svg) => {
  let serialized = new XMLSerializer().serializeToString(svg);
  let base64prefix = "data:image/svg+xml;base64,"
   let enc = base64prefix + btoa(serialized);
  return enc;
}

let copySvg = (svg, img) => {
  let enc = toBase64(svg);
  img.src = enc;
}

let copyImg = (img, canvas) => {
  context = canvas.getContext("2d");
  context.drawImage(img, 0, 0, 200.5, 200.5);
}

let main = () => {
   let svg = document.getElementById("svg");
   let img = document.getElementById("img");
   let canvas = document.getElementById("canvas");
   copySvg(svg, img);
   copyImg(img, canvas);
}

window.onload = main;

【问题讨论】:

  • searla 的回答是正确的,您可能使用的是高 dpi 显示器。不相关,但仍然很重要,您需要等待图像已加载,然后才能在画布上绘制它(您的 codepen 对我不起作用),并且只有 chrome 支持在没有绝对高度和宽度属性的情况下绘制 svg。 Fixed pen

标签: javascript canvas svg html5-canvas


【解决方案1】:

SVG 和 Image 以高 DPI 隐式绘制,但您需要为画布显式处理这种情况。

如果您的设备有window.devicePixelRatio === 2,如果您增加画布大小并更新 drawImage 以匹配,您会看到更清晰的图像:

<!-- Change this -->
<canvas id="canvas" width="200" height="200"></canvas>
<!-- to -->
<canvas id="canvas" width="400" height="400"></canvas>

还有:

// change this:
context.drawImage(img, 0, 0, 200.5, 200.5);
// to:
context.drawImage(img, 0, 0, 400, 400);

Forked codepen

有关window.devicePixelRatio(和canvas 的backingStorePixelRatio)的更多详细信息,请参阅High DPI Canvas 上的html5rocks 文章

【讨论】:

  • 正确,但 backingStorePixelRatio 已被弃用,甚至从实现中删除(Safari 的实现除外,在前缀下)。
  • 如果我有机会多次投票,我刚刚做了,谢谢!
猜你喜欢
  • 2021-08-06
  • 2015-04-14
  • 1970-01-01
  • 2016-12-23
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
  • 2019-12-23
  • 2022-07-21
相关资源
最近更新 更多