9

.net 中的 LinearGradientBrush(或者甚至在整个 GDI+ 中?)似乎有一个严重的错误:有时,它会引入工件。(参见此处此处- 基本上,线性渐变的第一条线是在 endcolor 中绘制的,即从白色到黑色的渐变将以黑色线开始,然后以适当的白色到黑色渐变开始)

我想知道是否有人找到了解决方法?这是一个非常烦人的错误:-(

这是Artifacts的图片,注意有2个LinearGradientBrushes:

替代文字 http://img142.imageshack.us/img142/7711/gradientartifactmm6.jpg

4

5 回答 5

9

我在使用渐变画笔时也注意到了这一点。我唯一有效的解决方法是始终在所有边缘上创建比将要使用它绘制的区域大 1 像素的渐变画笔矩形。这可以保护您免受所有四个方面的问题。缺点是边缘使用的颜色与您指定的颜色相差很小,但这比绘图伪影问题要好!

于 2008-09-21T02:55:46.460 回答
5

您可以在矩形上使用漂亮的 Inflate(int i) 方法来获得更大的版本。

于 2008-09-21T03:05:14.720 回答
3

我会在上面巧妙地回答菲尔的回答(这确实是一个评论,但我没有那个特权)。我看到的行为与文档相反,文档中说:

起始线垂直于方向线并通过矩形的角之一。起点线上的所有点都是起点颜色。然后结束线垂直于方向线并穿过矩形的角之一。结束线上的所有点都是结束颜色。

也就是说,在某些情况下,您会得到一个像素环绕。据我所知(通过实验),我只有在矩形的宽度或高度为奇数时才会遇到问题。因此,为了解决这个错误,我发现当且仅当尺寸(扩展前)为奇数时,将 LinearGradientBrush 矩形增加 1 个像素就足够了。换句话说,始终将画笔矩形向上舍入宽度和高度的下一个偶数像素。

所以要填充一个矩形r,我使用类似的东西:

Rectangle gradientRect = r;
if (r.Width % 2 == 1)
{
    gradientRect.Width += 1;
}
if (r.Height % 2 == 1)
{
    gradientRect.Height += 1;
}
var lgb = new LinearGradientBrush(gradientRect, startCol, endCol, angle);
graphics.FillRectangle(lgb, r);

疯狂但真实。

于 2012-12-05T17:42:52.380 回答
1

至少使用 WPF,您可以尝试使用GradientStops 在边缘获得 100% 正确的颜色,即使在重绘时也是如此。

于 2008-10-22T22:11:36.853 回答
0

我在我的 C++ 代码中也遇到了伪像。解决问题的方法是为 Graphics 对象设置非默认 SmoothingMode。请注意,所有非默认平滑模式都使用坐标系,该坐标系绑定到像素的中心。因此,您必须正确地将矩形从 GDI 转换为 GDI+ 坐标:

    Gdiplus::RectF      brushRect;

    graphics.SetSmoothingMode( Gdiplus::SmoothingModeHighQuality );

    brushRect.X = rect.left - (Gdiplus::REAL)0.5;
    brushRect.Y = rect.top - (Gdiplus::REAL)0.5;
    brushRect.Width = (Gdiplus::REAL)( rect.right - rect.left );
    brushRect.Height = (Gdiplus::REAL)( rect.bottom - rect.top );

似乎 LinearGradientBrush 仅在高质量模式下才能正常工作。

于 2020-04-15T16:02:23.573 回答