HTML5 Canvas 和抗锯齿
如何在画布上启用抗锯齿。
下面的代码没有画出一条平滑的线:
var context = mainCanv.getContext("2d");
if (context) {
context.moveTo(0,0);
context.lineTo(100,75);
context.strokeStyle = "#df4b26";
context.lineWidth = 3;
context.stroke();
}
How to turn on the anti-aliasing on an canvas.
The following code doesn't draw a smooth line:
var context = mainCanv.getContext("2d");
if (context) {
context.moveTo(0,0);
context.lineTo(100,75);
context.strokeStyle = "#df4b26";
context.lineWidth = 3;
context.stroke();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您可以将画布平移半像素距离。
最初是物理像素之间的画布定位点。
You may translate canvas by half-pixel distance.
Initially the canvas positioning point between the physical pixels.
抗锯齿功能无法打开或关闭,由浏览器控制。
我可以关闭 HTML
Anti-aliasing cannot be turned on or off, and is controlled by the browser.
Can I turn off antialiasing on an HTML <canvas> element?
现在已经是 2018 年了,我们终于有了廉价的方法来解决这个问题......
事实上,由于 2d context API 现在有一个
filter
属性,并且此过滤器属性可以接受 SVGFilters,我们可以构建一个 SVGFilter,它只保留绘图中完全不透明的像素,从而消除默认的抗锯齿功能。因此,它本身不会停用抗锯齿功能,但在实现和性能方面提供了一种廉价的方法来在绘图时删除所有半透明像素。
我并不是真正的 SVGFilters 专家,因此可能有更好的方法,但例如,我将使用
节点仅抓取完全不透明的像素。对于那些不喜欢在 DOM 中附加
元素的人,您还可以将其保存为外部 svg 文件并设置
filter
属性到path/to/svg_file.svg#remove-alpha
。It's now 2018, and we finally have cheap ways to do something around it...
Indeed, since the 2d context API now has a
filter
property, and that this filter property can accept SVGFilters, we can build an SVGFilter that will keep only fully opaque pixels from our drawings, and thus eliminate the default anti-aliasing.So it won't deactivate antialiasing per se, but provides a cheap way both in term of implementation and of performances to remove all semi-transparent pixels while drawing.
I am not really a specialist of SVGFilters, so there might be a better way of doing it, but for the example, I'll use a
<feComponentTransfer>
node to grab only fully opaque pixels.And for the ones that don't like to append an
<svg>
element in their DOM, you can also save it as an external svg file and set thefilter
property topath/to/svg_file.svg#remove-alpha
.我不需要打开抗锯齿,因为默认情况下它是打开的,但我需要将其关闭。如果它可以关闭,那么它也可以打开。
当我处理画布角色扮演游戏时,我通常会关闭它,这样当我放大图像时就不会显得模糊。
I haven't needed to turn on anti-alias because it's on by default but I have needed to turn it off. And if it can be turned off it can also be turned on.
I usually shut it off when I'm working on my canvas rpg so when I zoom in the images don't look blurry.
这是一个解决方法,要求您逐像素绘制线条,但会防止抗锯齿。
基本上,您找到线的长度,然后逐步遍历该线,舍入每个位置并填充像素。
调用它
Here's a workaround that requires you to draw lines pixel by pixel, but will prevent anti aliasing.
Basically, you find the length of the line, and step by step traverse that line, rounding each position, and filling in a pixel.
Call it with
如果您需要对画布进行像素级控制,可以使用 createImageData和 putImageData。
HTML:
和 JavaScript:
此处的工作示例
If you need pixel level control over canvas you can do using createImageData and putImageData.
HTML:
And JavaScript:
Working sample here
所以我假设这现在有点不使用了,但一种方法实际上是使用
document.body.style.zoom=2.0;
但如果你这样做,那么你所有的画布测量都会有除以变焦。另外,将变焦设置得更高以获得更多锯齿效果。这很有用,因为它是可调节的。另外,如果使用此方法,我建议您使函数执行与 ctx.fillRect() 等相同的操作,但要考虑缩放。例如希望这有帮助!
另外,旁注:这也可以用来锐化圆形边缘,这样它们看起来就不会那么模糊。只需使用 0.5 等缩放即可!
so I am assuming this is kinda out of use now but one way to do it is actually using
document.body.style.zoom=2.0;
but if you do this then all of your canvas measurements will have to be divided by the zoom. Also, set the zoom higher for more aliasing. This is helpful because it is adjustable. Also if using this method, I suggest that you make functions to do the same asctx.fillRect()
etc. but with the zoom taken into account. E.g.Hope this helps!
Also, a sidenote: this can be used to sharpen circle edges as well so that they don't look as blurred. Just use a zoom such as 0.5!
我遇到了同样的问题,并且能够通过使用小阴影和线条上下文来获得更平滑的线条,例如:
I had the same issue and was able to get smoother lines by using a small shadow along with the line context, such as:
我需要 0.5 平移和像素数据操作的组合:
我在坐标中添加了 0.5。这可能可以通过
翻译
来完成。但这 0.5 很重要。如果没有它,左边缘像素和上边缘像素就会被推离图像。它还修复了一些不一致的舍入。原本应该是一条直线的地方出现了一些倾斜。然后将所有像素值四舍五入为 0 或 255。如果您需要不同的颜色,可以四舍五入到这些值而不是 0 或 255。
I needed a combination of the 0.5 translation and pixel data manipulation:
I added 0.5 to the coordinates. That could probably be done with a
translate
. But that 0.5 is important. Without it, the left edge pixels and the top edge pixels get pushed off of the image. It also fixed some inconsistent rounding. What should have been a straight line had some dips in it.Then just round all the pixel values to 0 or 255. If you need different colors, you can round to those values instead of 0 or 255.