【发布时间】:2015-10-22 11:55:46
【问题描述】:
我在 html5 画布中手动绘制单个像素。我只使用纯黑色和纯白色。只是稍微简化一下:
var canvas = document.querySelector(".main-canvas");
var ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = false;
var isNonNegativeInteger = function(val) {
return Number.isFinite(val) && val % 1 === 0 && val >= 0;
};
var paintPixel = function(x, y) {
if (!isNonNegativeInteger(x) ||
!isNonNegativeInteger(y) ) {
debugger;
}
ctx.fillRect( x, y, 1, 1 );
};
var clearPixel = function( x, y ) {
if (!isNonNegativeInteger(x) ||
!isNonNegativeInteger(y) ) {
debugger;
}
ctx.clearRect( x, y, 1, 1 );
};
我只传递整数作为 x 和 y 坐标。是的,我非常确定,我已经进行了测试。
我不是在操纵 RGB。所有像素保持黑色。我只是在操纵阿尔法。我发现的是,经过大量的绘画和清理,经过大量的来回,有一个微弱的视觉“重影”,其中由fillRect() 设置为完全不透明的黑色像素实际上并不是调用clearRect() 时将其alpha 重置为零。
我知道这一点是因为当我在受影响的像素邻域中调用 ctx.getImageData() 时,我看到像素数据 alpha 值中散布着低但非零的 alpha 值(3、5 或 12 等)。这是……疯狂的制造。有趣的是,我还看到黑色像素的一些非 255 alpha 值,这也是有问题的,但在视觉上不像“脏”白色那样令人反感。
这些是大像素网格,每帧有数千个绘制调用。所以我不愿意使用getImageData() 和putImageData() 手动设置alpha,因为它们很慢。问题在于clearRect() 并没有按照它上面所说的那样做。
非常感谢任何建议。
【问题讨论】:
-
如果您仍然保持所有像素为黑色,则可以使用 fillRect 代替。您是否在任何地方更改转换矩阵?你测试过多个浏览器吗?
-
如何用fillRect“擦除”?将 ctx.fillStyle 设置为零 alpha 仅意味着填充完全没有效果。没有变换矩阵。在 FF 和 Chrome 中看到类似的结果。
-
Here 有更多相关信息。
-
不,我绝对不建议这样做。阅读下面的答案,以及问题上的 cmets。
-
有两件事值得细细琢磨。 1. 低 alpha 值 (drawImage,则允许浏览器进行可能影响 alpha 的 gamma 校正。如果没有代码,很难进一步分析,但我强烈怀疑当您以 1 个像素的宽度和高度重复
fillRect时,您正在与浏览器的抗锯齿算法发生冲突。
标签: canvas html5-canvas