我可以closuresHTML <canvas>元素的抗锯齿function吗?

我正在玩弄<canvas>元素,绘制线条等。

我注意到,我的对angular线是antialiased。 我更喜欢看看我在做什么 – 有没有办法把这个functionclosures?

现在有图像context.imageSmoothingEnabled = false

但是,没有任何东西明确地控制线条绘制。 您可能需要使用getImageDataputImageData来绘制自己的线( 难度 putImageData

在坐标上绘制1-pixel线,如ctx.lineTo(10.5, 10.5) 。 在点(10, 10)绘制一条像素线意味着该位置上的这个1像素从9.510.5 ,这导致在canvas上绘制两条线。

如果你有很多单像素线条,并不总是需要将0.5添加到你想绘制的实际坐标上的一个很好的技巧就是在整个canvas开始处ctx.translate(0.5, 0.5)

它可以在Mozilla Firefox中完成。 添加到您的代码:

 contextXYZ.mozImageSmoothingEnabled = false; 

在Opera中,它目前是一个function请求,但希望它会很快添加。

它必须是抗锯齿vectorgraphics

对于涉及非整数坐标(0.4,0.4)的vectorgraphics的正确绘图,抗锯齿是必需的 ,除了极less数的客户端之外,所有这些都是非常less的。

当给定非整数坐标时,canvas有两个选项:

  • Antialias – 根据整数坐标与非整数坐标的距离(四舍五入误差)绘制坐标周围的像素。
  • 舍入 – 将一些舍入函数应用于非整数坐标(例如,1.4将变为1)。

稍后的策略将适用于静态graphics,尽pipe对于小graphics(半径为2的圆)曲线将显示清晰的步骤而不是平滑的曲线。

真正的问题是当graphics被翻译(移动)时 – 一个像素与另一个像素之间的跳跃(1.6 => 2,1.4 => 1),意味着形状的原点可能会相对于父容器跳跃(不断移动1个像素上/下和左/右)。

一些技巧

提示1 :通过缩放canvas(例如x),可以软化(或加固)抗锯齿,然后将自由比例(1 / x)应用于几何(不使用canvas)。

比较(不缩放):

几个矩形

(帆布比例:0.75;手动比例:1.33):

相同的矩形边缘较柔和

和(canvas比例:1.33;手动比例:0.75):

相同的矩形边缘较深

提示#2 :如果一个锯齿形的样子真的是你以后,尝试绘制每个形状几次(不擦除)。 每画一次,抗锯齿像素变暗。

比较。 绘制一次后:

几条路

画三次后:

同样的道路,但更黑暗,没有可见的抗锯齿。

 ctx.translate(0.5, 0.5); ctx.lineWidth = .5; 

有了这个组合,我可以画出漂亮的1px细线。

我想补充一点,当缩小图像和在canvas上绘图时,我遇到了麻烦,即使在放大时不使用,仍然使用平滑处理。

我解决了这个问题:

 function setpixelated(context){ context['imageSmoothingEnabled'] = false; /* standard */ context['mozImageSmoothingEnabled'] = false; /* Firefox */ context['oImageSmoothingEnabled'] = false; /* Opera */ context['webkitImageSmoothingEnabled'] = false; /* Safari */ context['msImageSmoothingEnabled'] = false; /* IE */ } 

你可以像这样使用这个函数:

 var canvas = document.getElementById('mycanvas') setpixelated(canvas.getContext('2d')) 

也许这对某个人有用。

我会使用自定义线algorithm(如Bresenham的线algorithm)绘制所有内容。 看看这个JavaScript实现: http : //members.chello.at/easyfilter/canvas.html

我认为这一定会解决你的问题。

注意一个非常有限的技巧。 如果您想制作一个2色图像,您可以使用颜色#000000在背景上绘制颜色#010101所需的任何graphics。 完成此操作后,您可以testingimageData.data []中的每个像素,并将其设置为0xFF,而不pipe其值是不是0x00:

 imageData = context2d.getImageData (0, 0, g.width, g.height); for (i = 0; i != imageData.data.length; i ++) { if (imageData.data[i] != 0x00) imageData.data[i] = 0xFF; } context2d.putImageData (imageData, 0, 0); 

结果将是一个非antialiased黑白图片。 这将不是完美的,因为会发生一些抗锯齿,但是这种抗锯齿将是非常有限的,形状的颜色非常像背景的颜色。