LinearGradientBrush工件解决方法?

时间:2008-09-21 02:45:23

标签: c# gdi+

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

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

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

alt text http://img142.imageshack.us/img142/7711/gradientartifactmm6.jpg

5 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:5)

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

答案 2 :(得分:3)

我会在上面回答菲尔的答案(这真是一个评论,但我没有这个特权)。我看到的行为与the documentation相反,后者说:

  

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

即在某些情况下,您可以获得单个像素环绕。据我所知(通过实验),当矩形的宽度或高度为奇数时,我才会遇到问题。因此,为了解决这个问题,我发现当且仅当维度(扩展前)是奇数时,将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);

疯狂但是真的。

答案 3 :(得分:1)

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

答案 4 :(得分: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似乎只能在高质量模式下正常工作。