Graphics.DrawPath 和 LinearGradientBrush 问题

Graphics.DrawPath and LinearGradientBrush issue

关于我几周前问的这个问题现在

考虑以下代码:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    Rectangle rect = new Rectangle(100, 100, 200, 100);
    using(LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Red, Color.Blue, 90))
    {
        using(Pen pen = new Pen(brush, 1))
        {
            pen.Alignment = PenAlignment.Inset;
            e.Graphics.DrawRectangle(pen, rect);
        }
    }            
}

产生这个结果...

为什么本该是蓝线的地方却出现了红线,我该如何解决?

Pen.Alignment = PenAlignment.Inset 无效!

笔(或图形绘制方法)倾向于在其边界之外绘制。我认为 Microsoft 认为这是一项功能,但我从未理解它。

尝试使用较小的矩形笔:

using (var brush = new LinearGradientBrush(rect, Color.Red, Color.Blue, 90)) {
  using (Pen pen = new Pen(brush, 1)) {
    e.Graphics.DrawRectangle(pen, new Rectangle(rect.X, rect.Y,
                                                rect.Width - 1, rect.Height - 1));
  }
}

好的,总结一下:DrawRectangle 总是 透支 1 个像素 (*),因此 LinearGradientBrush 以第一种颜色重新开始。

是的,Lars 有一个解决方案,但这里有一个有趣的替代方案:

  brush.WrapMode = WrapMode.TileFlipXY;

这可以确保渐变不会在必须透支时从头开始,而是在两个方向上反转,因此额外的像素以正确的颜色绘制,您不需要操作其中一个两个 Rectangle 尺寸..

好吧,如果你需要完全精确,它可能是第二好的,因为最后一行和最后一列的颜色将与其相邻的颜色相同..但不必处理两种尺寸可能是值得的..

(*) 这就是为什么您 不能 使用它来绘制 1x1 square/pixel。相反,您需要使用 FillRectangle..