我可以closuresHTML <canvas>元素的抗锯齿function吗?
我正在玩弄<canvas>
元素,绘制线条等。
我注意到,我的对angular线是antialiased。 我更喜欢看看我在做什么 – 有没有办法把这个functionclosures?
现在有图像context.imageSmoothingEnabled
= false
。
但是,没有任何东西明确地控制线条绘制。 您可能需要使用getImageData
和putImageData
来绘制自己的线( 难度 putImageData
。
在坐标上绘制1-pixel
线,如ctx.lineTo(10.5, 10.5)
。 在点(10, 10)
绘制一条像素线意味着该位置上的这个1
像素从9.5
到10.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黑白图片。 这将不是完美的,因为会发生一些抗锯齿,但是这种抗锯齿将是非常有限的,形状的颜色非常像背景的颜色。