如何避免在画布中填充区域之间的接缝? [英] How to avoid seams between filled areas in canvas?

查看:135
本文介绍了如何避免在画布中填充区域之间的接缝?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I fill adjacent areas in HTML5 Canvas or similar systems like Quartz or GDI+, I see a light colored seam on the shared edge. Here's an example, (code below):

我想我明白发生了什么,但没有修复。

I think I understand what's going on but don't have a fix. Each edge is anti-aliased against white, so instead of a mix of orange and blue you get a mix of orange, blue and white.

基本上,同一问题之前已被问过,但与少讨论和没有好的答案。

Essentially the same question has been asked before but with less discussion and no good answer.

一些解决方法涉及绘制第一个形状一点点在接缝或绘制一条线在接缝不会阻止

Some work-arounds that involve drawing the first shape a little bigger at the seam or drawing a line over the seam do not hold up over variations like with transparency or odd shape combinations.

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

Turning off anti-aliasing avoids the seam for APIs that support it, but then, of course, all the edges are jagged.

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

Is there a way to provide a hint to the renderer about the intended adjacency?

<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>


推荐答案


为渲染器提供关于预期邻接的提示?

Is there a way to provide a hint to the renderer about the intended adjacency?

不幸的是,默认情况下,反锯齿/子像素化我们不能关闭它。

Unfortunately no, anti-aliasing/sub-pixeling is on by default and we cannot turn it off.

有一些方法可以解决这个问题:

There are some ways I can think of to solve this:

在注释中使用markE提及的技术,并使用stroke n
拉伸多边形,这将导致它们重叠。您可以通过首先将 lineWidth 属性设置为 0.67 来减少影响。

1) Use the technique markE mention in comments and use stroke n to extrude the polygon which will cause them to overlap. You can reduce the impact by first setting the lineWidth property to 0.67.

2)通过将重叠线的坐标(通过添加到坐标或通过使用平移)平移一个像素来手动重叠。这给出比1更好的结果,因为这将仅在重叠区域而不是在所有侧面上挤出多边形。缺点是,你需要手动计算每个重叠,很快变得很痛苦,特别是如果你想动画他们。

2) Overlap manually by translating the coordinates (either by adding to the coordinate or by using translate) for the overlapping lines by one pixel. This gives a better result than 1 as this will only extrude the polygon in the overlapping area and not on all sides. The drawback however is that you need to manually calculate each overlapping which quickly becomes painful especially if you want to animate them as well.

3)实现一个线和填充算法(例如Bresenham)。这不是那么难,但它会减慢绘图,并显着地,如果你更新图形经常。好处是你知道线的绘制位置。缺点是你没有反锯齿,除非你也实现这一点,并在自己的价格性能明智。

3) implement a line and fill algorithm yourselves (for example Bresenham). This is not so hard but it will slow down the drawing, and noticeably so if you update the graphics often. The benefit is that you know exactly where the lines are drawn. The drawback is that you get no anti-aliasing unless you also implement this and at its own price performance wise.

4)1和3的组合,你使用canvas '使用Bresenham线算法填充和重绘重叠线。

4) A combination of 1 and 3 where you use canvas' fill and overdraw overlapping lines with a Bresenham line algorithm.

5)使用一个大的离屏画布,并绘制所有的缩放。然后最终将所有内容绘制到屏幕上的画布到目标大小(或改为使用CSS设置目标大小)。这将有助于伪装缝隙,也给你更清晰的线条,你可以保持你的原始坐标,但它需要更多的像素和更多的内存处理,因此它慢,但不慢,像手动线/填充方法与3。

5) Use a large off-screen canvas and draw everything up-scaled. Then finally draw everything to the on-screen canvas to the target size (or instead set target size using CSS). This will help camouflaging the gap and also give you sharper lines and you can keep your original coordinates as well, but it require more processing of pixels and more memory so it's slower but not as slow as a manual line/fill approach as with 3.

这篇关于如何避免在画布中填充区域之间的接缝?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆