具有GDI / Winforms的抗锯齿贝塞尔曲线 - c#. net

3

我正在尝试在一个Winforms应用中绘制贝塞尔曲线。

我正在计算贝塞尔点,并使用DrawImage绘制自定义图像刷在每个点上。

然而,我并没有得到我希望的结果——在弯曲点处,曲线不够平滑(注意Y坐标增加/减少了1px):

Choppy curve

Here is an example of a "nice" curve quickly painted in "photoshop" with the brush tool:

Nice curve

Does anyone know how to achieve this kind of "antialiasing"?

I'm basically doing this:

        using(var g = Graphics.FromImage(bitmap))
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            //points - an array with calculated beziere curve points
            //image - the "image brush" that is painted at each curve point
            foreach (var p in points)
            {
                g.DrawImage(image, p);
                g.Flush();
            }
        }

Thank you!


4
等一下,用DrawImage绘制贝塞尔曲线?使用带有TextureBrush的Pen来使用DrawBezier。 - Hans Passant
嗨,是的 - 我最初尝试了那个,但是当曲线弯曲时,纹理不会跟随弯曲 - 它只是简单地将纹理平铺为背景。除非我错过了某些配置? - user506262
没错,你无法从Graphics类中获取这个。我不知道有哪个常见的图形库可以做到这一点。如果这很容易,没有人会购买Photoshop,我猜。 - Hans Passant
2个回答

2

可能是因为您的points集合包含类型为Point的结构体,该结构体使用Int32 - 因此,您自己量化了您的点。

尝试改用PointF - 这将使您能够在任意位置绘制图像,而不是围绕整数位置进行量化。


这是 var 多么糟糕的另一个例子。当像 for each (var p in Points) 这样的行中使用它时,它除了掩盖对象/结构类型外,什么也没有完成,在这种情况下只会掩盖问题的根源。 - MusiGenesis
真的,但在这种情况下,我会说是“轮子后面的狗屎”导致了问题 :) - 我实际上甚至不知道你可以获得比屏幕上的像素更高的精度,那么int或float有什么关系呢 :) - 我确保转换在X / Y方向上不超过1px ... 但显然在幕后有一些魔法 :O - user506262

1

你实际上并没有使用GDI来绘制线条,因此你的Smoothing和InterpolationMode设置没有任何效果。你只是在每个点数组中绘制一幅图像,所以没有连接这些点或任何类型的抗锯齿。尝试将你的点集合转换为路径,并使用g.DrawPath来绘制你的曲线。

一个更简单的例子,虽然没有贝塞尔曲线,但可以使用DrawLines方法。例如:

g.DrawLines(Pens.Blue, points.ToArray());

对于DrawLines和DrawPath,甚至不需要使用循环。DrawLines就像是穷人版的DrawPath...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接