如何使用canvas drawImage处理质量损失?

时间:2017-04-27 11:21:05

标签: javascript canvas svg html5-canvas

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

问题:当我将base64编码的SVG作为src传递给图像时,它看起来像原始SVG图像一样清晰。但是,如果我将拍摄此图像并在画布中使用它(通过context.drawImage) - 它的质量会更差: enter image description here

问题是 - 如何在画布中绘制基于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;

1 个答案:

答案 0 :(得分:3)

SVG和Image是在高DPI时隐式绘制的,但你需要为canvas显式处理这种情况。

如果您的设备有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(以及画布backingStorePixelRatio)的详细信息,请参阅High DPI Canvas上的html5rocks文章