我在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。所有像素都保持黑色。我只是在操纵alpha。我所发现的是,经过大量的绘画和清理,经过大量的来回,有一个微弱的视觉“重影”,其中被fillRect()
设置为完全不透明的黑色像素是<{1}}被调用时实际上没有将alpha重置为零。
我知道这一点,因为当我在受影响的像素邻域中调用clearRect()
时,我看到像素数据alpha值中出现了低但非零的alpha值(3,5或12等)。这是......疯狂的制作。有趣的是,我也看到了黑色像素的一些非255 alpha值,这些值也存在问题,但对“脏”白人的视觉攻击性较小。
这些是大像素网格,每帧有数千个绘制调用。所以我不愿意使用ctx.getImageData()
和getImageData()
来手动设置alpha,因为它们很慢。问题在于putImageData()
没有按照它所说的那样做。
非常感谢任何建议。
答案 0 :(得分:0)
这真的很奇怪,我能想到的唯一原因是你的x和y坐标不是int
。
在浮点位置绘制确实会在clearRect
上创建一个抗锯齿工件:
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.textBaseline = "middle"
var paintPixel = function(x, y) {
ctx.fillRect(x, y, 1, 1);
};
var clearPixel = function(x, y) {
ctx.clearRect(x, y, 1, 1);
};
var i = 0;
for (i = 0; i < 25; i += .1) {
paintPixel(i, 10);
clearPixel(i, 10);
}
ctx.fillText('float', 30, 10)
for (i = 0; i < 25; i++) {
paintPixel(i, 30);
clearPixel(i, 30);
}
ctx.fillText('int', 30, 30)
// an other solution could have been to use globalCompositeOperation
var gCOClear = function(x, y) {
ctx.globalCompositeOperation = 'destination-out';
ctx.fillRect(x, y, 1, 1);
ctx.globalCompositeOperation = 'source-over';
}
for (i = 0; i < 25; i += .1) {
paintPixel(i, 50);
gCOClear(i, 50);
}
ctx.fillText('gCO float', 30, 50)
for (i = 0; i < 25; i++) {
paintPixel(i, 70);
gCOClear(i, 70);
}
ctx.fillText('gCO int', 30, 70)
所以解决方案是:要么在绘制前围绕坐标,要么比你绘制的要小一些。
但正如您指定的那样,您绝对肯定“只能将整数作为x和y坐标传递”,这可能不是您的问题......
另外,请注意,ctx.imageSmoothingEnabled对绘制方法没有影响,例如fillRect()
和clearRect()