【问题标题】:How prevent blurry drawing on canvas when using putImageData?使用 putImageData 时如何防止画布上的模糊绘图?
【发布时间】:2016-08-13 15:13:15
【问题描述】:

我想用putImageData 在画布上作画。但由于某种原因,绘制的像素模糊,我不知道为什么。这是一个最小的例子:

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
    <style>
       html, body, canvas { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }
    </style>
  </head>
  <body oncontextmenu="return false;">
    <canvas id='canvas'></canvas>
    <script type='text/javascript'>
      let canvas = document.getElementById('canvas');

      let ctx = canvas.getContext("2d");
      ctx.imageSmoothingEnabled = false;
      ctx.mozImageSmoothingEnabled = false;
      ctx.webkitImageSmoothingEnabled = false;
      ctx.msImageSmoothingEnabled = false;

      let uarr = new Uint8ClampedArray(4);
      uarr[0] = 0;
      uarr[1] = 0;
      uarr[2] = 0;
      uarr[3] = 255;

      let imgData = new ImageData(uarr , 1, 1);
      ctx.putImageData(imgData, 20, 20);
    </script>      
  </body>
</html>

这应该在20,20 坐标处绘制一个黑色像素,但由于某种原因它看起来很模糊。

如何强制绘制锐边?

【问题讨论】:

  • 似乎并非所有浏览器都支持这一点。 Safari 似乎是个顽固分子。你用的是什么浏览器?
  • 在 chrome 和 Safari 中检查
  • 哦等等。试试canvas.width = window.innerWidthtcanvas.height = window.innerHeight。您目前正在使用 CSS 将标准尺寸的画布拉伸到屏幕大小,但这不是画布的工作原理,它更像是具有可拉伸的预定义尺寸的图像。
  • 我现在感觉有点傻,哈哈。我以前使用过画布,不知道我怎么会错过。
  • 哈没问题,当它直视你的脸时,你仍然看不到它。事后看来很明显。

标签: javascript canvas


【解决方案1】:

您需要设置画布的宽度和高度属性,因为您的 CSS 会将默认大小的画布拉伸到屏幕大小,就像拉伸过小的图像一样。之后ctx.imageSmoothingEnabled 应该可以正常工作了。

var canvas = document.getElementById('canvas');

// This will stretch correctly
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;

var uarr = new Uint8ClampedArray(4);
uarr[0] = 0;
uarr[1] = 0;
uarr[2] = 0;
uarr[3] = 255;

var imgData = new ImageData(uarr , 1, 1);
ctx.putImageData(imgData, 20, 20);
html, body, canvas { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }
&lt;canvas id='canvas'&gt;&lt;/canvas&gt;

正如@Kaido 在下面的 cmets 中提到的那样,imageSmoothingEnabled 并不是这样工作的。查看他的小提琴,更深入地了解它的用途。

【讨论】:

  • imageSmoothingEnabled 仅适用于 drawImage 方法。 putImageData 不会创建任何抗锯齿(这是唯一默认情况下不创建的画布 API 方法),它只会将原始像素设置为 imageData 的数据中。 jsfiddle.net/w8deLfo1
  • 很好,虽然有一些简单的方法可以解决这个问题(比如缓冲画布)。
  • 没有什么可解决的,只是你不需要为putImageData设置imageSmoothingEnabled。
  • 没错,但我认为这一定是有原因的:)
  • 你的意思是 OP 设置这个的原因?我想这是因为他正在为他的 css 抗锯齿寻找解决方案,并且听说过 imageSmoothingEnabled,而在他的情况下它不会做任何事情,因为它实际上仅限于 drawImage
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
  • 2015-11-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多