7

当我在 HTML5 Canvas 或 Quartz 或 GDI+ 等类似系统中填充相邻区域时,我在共享边缘上看到浅色接缝。这是一个例子,(下面的代码):

在此处输入图像描述

我想我明白发生了什么,但没有解决办法。每个边缘都针对白色进行了抗锯齿处理,因此不是橙色和蓝色的混合,而是橙色、蓝色和白色的混合。

基本上之前已经问过同样的问题,但讨论较少,也没有好的答案。

一些涉及在接缝处将第一个形状画得稍大一点或在接缝上画一条线的变通方法不能抵抗诸如透明度或奇数形状组合之类的变化。

关闭抗锯齿可以避免支持它的 API 的接缝,但是当然,所有的边缘都是锯齿状的。

有没有办法向渲染器提供有关预期邻接的提示?

<canvas id="myCanvas" width="300" height="150" /> <script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(100,0);  ctx.lineTo(115,150);  ctx.lineTo(300, 50);
ctx.closePath();  ctx.fillStyle="#885533";  ctx.fill();

ctx.beginPath();
ctx.moveTo(0,50);  ctx.lineTo(100,0);  ctx.lineTo(115,150);
ctx.closePath();  ctx.fillStyle="#335588";  ctx.fill();
</script>  </body>  </html>
4

2 回答 2

1

有没有办法向渲染器提供有关预期邻接的提示?

不幸的是,没有,默认情况下抗锯齿/子像素化是打开的,我们无法将其关闭。

我可以想到一些方法来解决这个问题:

1) 使用评论中提到的技术 markE 并使用 stroke n 来挤压多边形,这将导致它们重叠。您可以通过首先将lineWidth属性设置为 来减少影响0.67

2)通过将重叠线的坐标(通过添加到坐标或使用平移)平移一个像素来手动重叠。这提供了比 1 更好的结果,因为这只会在重叠区域中挤出多边形,而不是在所有边上。然而,缺点是您需要手动计算每个重叠,这很快就会变得很痛苦,特别是如果您还想为它们设置动画。

3)自己实现线条和填充算法(例如Bresenham)。这并不难,但它会减慢绘图速度,如果您经常更新图形,这一点会很明显。好处是您可以准确地知道画线的位置。缺点是你没有抗锯齿,除非你也以它自己的价格性能来实现它。

4) 1 和 3 的组合,您使用画布的填充并使用 Bresenham 线算法过度绘制重叠线。

5)使用一个大的离屏画布并按比例绘制所有内容。然后最后将所有内容绘制到屏幕上的画布到目标大小(或者使用 CSS 设置目标大小)。这将有助于掩盖间隙,并为您提供更清晰的线条,并且您也可以保留原始坐标,但它需要更多的像素处理和更多的内存,因此速度较慢但不如手动线条/填充方法慢 3.

于 2013-10-14T04:41:51.530 回答
1

如果您在透明画布上绘图并且您的形状不重叠,您可以简单地设置ctx.globalCompositeOperation = "lighter"

你的例子 globalCompositeOperation =

这意味着每个形状将使用简单的加法而不是典型的alpha 混合将其贡献与其像素的先前内容结合起来。在这种情况下,这正是您想要的。

于 2018-11-14T03:42:41.863 回答