繁体   English   中英

使用GDI +使用不同颜色绘制线条的快捷方法?

[英]Fast way to draw lines using different Color using GDI+?

我有一个动态List of Point,可以随时添加新Point。 我想绘制线条以使用不同的颜色连接它们。 颜色基于这些点的索引。 这是代码:

    private List<Point> _points;
    private static Pen pen1 = new Pen(Color.Red, 10);
    private static Pen pen2 = new Pen(Color.Yellow, 10);
    private static Pen pen3 = new Pen(Color.Blue, 10);
    private static Pen pen4 = new Pen(Color.Green, 10);

    private void Init()
    {
        // use fixed 80 for simpicity
        _points = new List<Point>(80);

        for (int i = 0; i < 80; i++)
        {
            _points.Add(new Point(30 + i * 10, 30));
        }
    }

    private void DrawLinesNormal(PaintEventArgs e)
    {
        for (int i = 0; i < _points.Count-1; i++)
        {
            if (i < 20)
                e.Graphics.DrawLine(pen1, _points[i], _points[i + 1]);
            else if (i < 40)
                e.Graphics.DrawLine(pen2, _points[i], _points[i + 1]);
            else if (i < 60)
                e.Graphics.DrawLine(pen3, _points[i], _points[i + 1]);
            else
                e.Graphics.DrawLine(pen4, _points[i], _points[i + 1]);
        }
    }

当我有新的高速进入时,我发现这种方法不够快。 有没有办法让它更快? 我做了一些研究,有人说使用GraphicsPath可能会更快,但如何?

[更新]我收集了一些可能的优化:

  1. 使用GrahpicsPath, 原始问题
  2. 更改图形质量(例如SmoothingMode / PixelOffsetMode ...),也调用SetClip指定要渲染的唯一必要区域。

在不降低质量或更改为更快的渲染器(GDI,OpenGL,DirectX)的情况下,您将无法从代码中挤出更多的速度。 但是GDI通常会快得多(可能是2倍),而DirectX / OpenGL可以更快(可能是10倍),这取决于你绘制的内容。

使用Path的想法是将许多(在您的示例中为20行)行批处理为单个方法调用,而不是将DrawLine调用20次。 如果您可以将传入数据排列为绘图例程的正确列表格式,这将使您受益。 否则,您将必须将点复制到正确的数据结构中,这将浪费您通过批处理路径获得的大量时间。 对于DrawPath,您可能必须从点数组创建GraphicsPath,这可能导致没有时间保存。 但是如果你不得不多次绘制相同的路径,你可以缓存它,然后你可以看到净收益。

如果将新点添加到列表中,但不删除旧点(即,您始终只是向显示添加新行),那么您将能够使用屏幕外位图来存储到目前为止渲染的线。 这样,每次添加一个点时,都会绘制一条线,而不是每次都绘制所有80条线。

这完全取决于你想要做什么。

没有真正帮助提高性能,但我会把笔也放到一个列表中并以这种方式写下所有这些行:

int ratio = _points.Count / _pens.Count;

for (int i = 0; i < _points.Count - 1; i++)
{
    e.Graphics.DrawLine(_pens[i / ratio], _points[i], _points[i + 1]);
}

这与您使用System.Drawing的速度差不多。 您可能会看到使用Graphics.DrawLines()获得一些收益,但您需要以不同方式格式化数据,以便使用相同的笔一次性绘制一堆线。 我非常怀疑GraphicsPath会更快。

提高速度的一个可靠方法是降低输出质量。 设置Graphics.InterpolationModeInterpolationMode.LowGraphics.CompositingQualityCompositingQuality.HighSpeedGraphics.SmoothingModeSmoothingMode.HighSpeedGraphics.PixelOffsetModePixelOffsetMode.HighSpeedGraphics.CompositingModeCompositingMode.SourceCopy

我记得一次速度测试,有人将Graphics与P / Invoke比作GDI例程,并且对P / Invoke速度快得多,我感到非常惊讶。 你可能会检查出来。 我会看看我是否能找到这种比较...... 显然这是针对Compact Framework的,因此很可能不适用于PC。

另一种方法是使用Direct2D,如果你有合适的硬件,它可以比GDI更快。

太晚了,但可能还有人需要解决方案。

我用类似的(但不是完全/相等的)GDI +语法创建了小型库GLGDI +,它运行在OpenTK上: http//code.google.com/p/glgdiplus/

我不确定稳定性,它与DrawString有一些问题(来自OpenTK的TextPrint问题)。 但是如果你需要为你的实用程序提升性能(比如我的情况下的级别编辑器),它可以是解决方案。

您可能希望查看Brush对象,并且您确实无法通过GDI +程序获得接近实时性能,但只要对象的几何和数量保持在合理的范围内,您就可以轻松维护体面的fps。 。 至于画线,我不明白为什么不。

但是如果你达到了你认为最佳的点,那就是画线......你应该考虑一个不同的图形堆栈,如果你喜欢.NET但是有非托管API的问题,比如OpenGL和DirectX,那就去吧使用WPF或Silverlight,它非常强大。

无论如何,您可以尝试设置System.Drawing.Drawing2D.GraphicsPath,然后使用System.Drawing.Drawing2D.PathGradientBrush以这种方式应用颜色。 这是一个单缓冲的绘制调用,如果你无法获得足够的性能。 除了GDI +,你必须完全采用其他方法

根本不是GDI(+),但解决这个问题的完全不同的方法是使用一块内存,将线条绘制到那里,将其转换为Bitmap对象,以便立即绘制您需要显示线条的位置。

当然,这在快速的方式上取决于极端

  • 在所选择的内存表示中绘制给定颜色的线条
  • 将其转换为要显示的Bitmap

我想,不是在.NET Framework中,而是在第三方库中? 对于像这样的东西,Silverlight中没有类似的位图编写器吗? (我自己还没有进入Silverlight ......)

至少它可能是开箱即用的方法。 希望能帮助到你。

我认为你必须在绘图后处理笔对象和e.Graphics对象。 如果你在onPaint()中编写drawLine代码,还有一件事情会更好。

 just override onPaint() method it support better drawing and fast too.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM