6

是否可以更改PowerPacks.LineShape平滑模式?

我尝试使用此代码(继承的类LineShape):

  Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim g As Graphics = e.Graphics   

    ' no difference when changing the SmoothingMode ' 
    g.SmoothingMode = SmoothingMode.AntiAlias 

    Using pen As New Pen(Color.Blue, 3)
      g.DrawLine(pen, X1, Y1, X2, Y2)
    End Using

    ' MyBase.OnPaint(e) '
  End Sub

我总是有相同的结果,如下所示: alt text http://lh6.ggpht.com/_1TPOP7DzY1E/S3v1IbxlbCI/AAAAAAADD4/q1Y9kP8wJ0g/s800/Capture2.png

=======

编辑

更新了测试:

  Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    Dim g As Graphics = e.Graphics

    Dim oldmode As SmoothingMode = g.SmoothingMode

    Using pen As New Pen(Color.Blue, 3)
      g.SmoothingMode = SmoothingMode.AntiAlias
      g.DrawLine(pen, X1, Y1, X2, Y2)
      g.SmoothingMode = SmoothingMode.None
      g.DrawLine(pen, X1 + 50, Y1, X2 + 50, Y2)
    End Using

    g.SmoothingMode = oldmode
    g.Flush()

    'MyBase.OnPaint(e)'
  End Sub

结果(不考虑标签和圆圈):

替代文字 http://lh3.ggpht.com/_1TPOP7DzY1E/S447qYvTqzI/AAAAAAAADE8/eP3kCLqQJbk/s800/Capture2.png

显然平滑模式没有被忽视......

4

4 回答 4

4

SmoothingMode 肯定会影响您的输出

这是我最近用于以最小质量损失调整图像大小的一些设置:

graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

InterpolationMode 可能与您的示例无关,但 PixelOffsetMode 可能是。让我启动一个快速测试应用程序。

更新:这是快速测试应用程序,SmoothingMode 肯定会影响我绘制的线条。

private void Form1_Load(object sender, EventArgs e)
{
    foreach (var value in Enum.GetValues(typeof(SmoothingMode)))
    {
        _ComboBoxSmoothingMode.Items.Add(value);
    }

    foreach (var value in Enum.GetValues(typeof(PixelOffsetMode)))
    {
        _ComboBoxPixelOffsetMode.Items.Add(value);
    }

    _ComboBoxPixelOffsetMode.SelectedIndex = 0;
    _ComboBoxSmoothingMode.SelectedIndex = 0;
}

private void _ButtonDraw_Click(object sender, EventArgs e)
{
    using (Graphics g = _LabelDrawing.CreateGraphics())
    {
        g.Clear(Color.White);

        if (_ComboBoxPixelOffsetMode.SelectedItem != null && (PixelOffsetMode)_ComboBoxPixelOffsetMode.SelectedItem != PixelOffsetMode.Invalid)
        {
            g.PixelOffsetMode = (PixelOffsetMode)_ComboBoxPixelOffsetMode.SelectedItem;
        }

        if (_ComboBoxSmoothingMode.SelectedItem != null && (SmoothingMode)_ComboBoxSmoothingMode.SelectedItem != SmoothingMode.Invalid)
        {
            g.SmoothingMode = (SmoothingMode)_ComboBoxSmoothingMode.SelectedItem;
        }

        using (Pen pen = new Pen(Color.Blue, 3))
        {
            g.DrawLines(pen, new[] { new Point(0, 0), new Point(25, 50), new Point(_LabelDrawing.Width - 25, _LabelDrawing.Height - 50), new Point(_LabelDrawing.Width, _LabelDrawing.Height), });
        }
    }
}

SmoothingMode:抗锯齿无

SmoothingMode.AntiAlias http://www.ccswe.com/temp/SmoothingMode_AntiAlias.png SmoothingMode.None http://www.ccswe.com/temp/SmoothingMode_None.png

更新:正如 Morbo 指出的,如果Graphics呈现给您的PaintEventArgs对象Graphics与最终用于显示的对象不同,那么更改平滑可能不会有任何效果。Graphics尽管如果那是记忆中的对象Image或其他东西,我不会期望有如此巨大的差异。

希望我能提供更多。也许如果我更好地理解LineShape它给你的东西和你使用它的理由,而不是仅仅使用 Graphics.DrawLine() 方法之一。

我质疑您使用的原因LineShape是您正在覆盖它的 OnPaint 并绘制自己的线。似乎你可以简化你的应用程序并放弃LineShape但也许我错过了一些东西。


更新:LineShape好的,你为什么使用then是有道理的。在这一点上我能提供的唯一建议是在您的面板或 LineShape 中覆盖 OnPaint,在调用基本事件之前尝试在那里设置平滑模式。就像是:

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphichs.SmoothingMode = SmoothingMode.AntiAlias;
    base.OnPaint(e);
}
于 2010-02-26T17:22:18.593 回答
2

你的显示设置是什么?至少 24 位颜色?

我可以确认,从 LineShape 派生一个类并像您展示的那样覆盖 OnPaint 实际上确实会按预期影响线渲染。我还可以确认 Power Pack 3.0 和 Visual Studio 2010 中的版本都专门在 LineShape.DrawInternal 方法中使用 AntiAlias。

我从一个空白的 .NET 2.0 Windows 窗体应用程序开始。我添加了以下与您的几乎相同的类和一个仅包含 ShapeContainer 和对角 MyLine 形状的表单。

Imports Microsoft.VisualBasic.PowerPacks

Public Class MyLine
    Inherits LineShape

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)

        Dim g As Graphics = e.Graphics

        'g.SmoothingMode = SmoothingMode.AntiAlias '

        Using pen As New Pen(Color.Blue, 3)
            g.DrawLine(pen, X1, Y1, X2, Y2)
        End Using

        'MyBase.OnPaint(e) '

    End Sub

End Class

如果我按原样使用上述代码运行项目,则该行是别名(锯齿状)。如果我取消注释 SmoothingMode 设置,该线将变为抗锯齿(平滑)。

所以它肯定应该工作。我知道这似乎是一个愚蠢的问题,但是您是否检查过以确保您的代码在调试器中被命中?您是否尝试在 DrawLine 之后立即调用 Graphics.Flush()?

另外,您使用的是哪个版本的 PowerPack?就像我说的,我可以在 Reflector 中非常清楚地看到 LineShape.DrawInternal 在 try/finally 块中专门将 SmoothingMode 设置为 AntiAlias。它在返回之前恢复旧的平滑模式。但是在您的示例中,您甚至不应该点击它,因为您没有调用基本方法。

于 2010-03-03T05:59:37.707 回答
2

从我在 Reflector 中可以看出,PowerPack LineShape 组件使用来自容器的原始 Paint 事件的 Graphics 对象进行绘制。更改您获得的 Graphics 对象的属性可能会影响容器中在您的形状之后绘制的所有其他内容。

您的示例中包含哪些 LineShape 对象?(如果它是自定义绘制的控件,您是否会在某个时候创建​​位图?如何创建?)如果它们位于颜色深度较低的自定义控件中,则可能是问题的根源。LineShape 在我的机器上默认绘制抗锯齿。

于 2010-02-26T17:47:02.717 回答
0

问题在于我的开发模式:通过虚拟 PC 上的远程桌面连接。

在我的例子中,RDC 没有考虑 AntiAlias 图形属性。

更多细节:您在 Virtual PC 上开发时遇到过问题吗?

感谢大家的参与,抱歉,这不是真正的 .NET 问题。

于 2010-03-03T16:47:17.223 回答