【问题标题】:update move mouse更新移动鼠标
【发布时间】:2016-12-27 02:23:55
【问题描述】:

我遇到了一个关于 GDI+ 效率的问题。 有几个变量和方法 如下: 1.Points,如A(表示坐标点,如X Y Z)、B、C、D、E等

2 名为Cmd1的列表,用于线程加点

3.Paint 方法,在该方法中,连接线的点的集合

4.线程用于不断添加新点,如F、G、H、I、J等

在 Paint Method 中,我使用 g.DrawLine() 来链接 a 和 b,c,d,e。 在线程中,当我添加新点时,我将调用无效来刷新组件。 所以我的问题是,积分越来越多,如何才能保持高效率,重绘,

不要从a点开始重新画线。

Sub DrawGLines2(g As Graphics)

    g.SmoothingMode = SmoothingMode.HighSpeed
    Dim Pen As New Pen(Brushes.White)
    Dim i As Int32
    'Dim c As Int32
    Dim preCmd1 As Cmd1
    Try
        For Each cmd As Cmd1 In Cmd1s            
                Dim pfs() As PointF = cmd.PointFs.ToArray
                If preCmd1 IsNot Nothing Then
                    g.DrawLine(Pen, cmd.PointFs(0), preCmd1.PointFs(0))
                End If
                preCmd1 = cmd
            End If

        Next
    Catch ex As Exception
        Debug.Print(ex.Message)
    End Try
End Sub

Private Sub Sheet_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    If Me.Cmd1s.Count>0 Then
        DrawGLines2(e.Graphics) 
    End If
End Sub

Public Sub AddPoint(x As Double, y As Double, z As Double, Optional G As Int32 = -1)
    Dim cmd1 As DrvSimu.Cmd1 = Nothing
    If cmd1 Is Nothing Then
        cmd1 = New DrvSimu.Cmd1
        Me.Cmd1s.Add(cmd1)
    End If

    Dim pf3d As New PointF3D(x, y, z)
    cmd1.PointF3Ds.Add(pf3d)

    Me.Invalidate()

End Sub

线程会调用AddPoint添加a,b,c,d,e点,并使用invalid方法刷新,当我调用invalid时,每个的“For Each cmd As Cmd1 In Cmd1s”将从A点开始,所以当点越来越多时,如何保持高效率,重绘,不要从A点开始重新画线

【问题讨论】:

    标签: visual-foxpro


    【解决方案1】:

    这取决于你到底想做什么。

    一种可能性是您当前正在使用的那种。在每次无效时,您都会重新绘制所有行。根据绘图质量和 cpu,您可以绘制更多或更少的线,但应该可以每毫秒至少绘制 10 条线。

    如果您只添加线条并且不需要删除或修改它们,您也可以将所有线条绘制到位图上,并且在无效时您只将该图像绘制到屏幕上。这样,您只需在添加新线时将它们绘制到图片上。这种方法的问题是,如果您想要缩放或平移该区域或者想要移除线条,您仍然需要完全重绘。

    作为起点,请参阅 Graphics.FromImage(...) 方法。 使用 Pixelformat Format32bppARGB 以获得最佳性能。

    编辑:

    public partial class LineForm : Form
    {
        private Bitmap lineBitmap = null;
    
        private List<Tuple<PointF,PointF>> lines = new List<Tuple<PointF,PointF>>();
    
        private List<Tuple<PointF,PointF>> newLines = new List<Tuple<PointF,PointF>>();
    
        // must be set if you remove line, pan or zoom the view and if you resize the form.
        private bool redrawAll = false;
    
        public LineForm()
        {
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.OnPaint);
            this.Resize += new System.EventHandler(this.OnResize);
        }
    
        private void OnResize(object sender, EventArgs e)
        {
            if (this.lineBitmap!= null)
            {
                this.lineBitmap.Dispose();
            }
    
            if (this.Width <= 0 || this.Height <= 0)
            {
                return;
            }
    
            this.lineBitmap = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppPArgb);
            this.redrawAll = true;
        }
    
        private void OnPaint(object sender, PaintEventArgs e)
        {
            Graphics lineGfx = Graphics.FromImage(this.lineBitmap);
            // Settings for best drawing Performance. Must be adjusted for better quality
            lineGfx.CompositingQuality = CompositingQuality.HighSpeed;
            lineGfx.InterpolationMode = InterpolationMode.NearestNeighbor;
            lineGfx.SmoothingMode = SmoothingMode.None;
            lineGfx.PixelOffsetMode = PixelOffsetMode.None;
            lineGfx.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            lineGfx.CompositingMode = CompositingMode.SourceCopy;
    
            // Only clear the Image and draw all lines if necessary
            if(this.redrawAll)
            {
                lineGfx.Clear(Color.Transparent);
                foreach(Tuple<PointF,PointF> line in this.lines)
                {
                    lineGfx.DrawLine(Pens.Black, line.Item1, line.Item2);
                }
            }
    
            // Draw the new Lines to the Bitmap and store them to lines list
            foreach(Tuple<PointF,PointF> newline in this.newLines)
            {
                lineGfx.DrawLine(Pens.Black, newline.Item1, newline.Item2);
                tihs.lines.Add(newLine);
            }
    
            // Clear the newLines List as the liones are added to the lines List now.
            this.newLines.Clear();
    
            // Draw the Bitmap to the screen
            e.Graphics.DrawImageUnscaled(this.lineBitmap,0,0);
        }
    
        private void AddLine(PointF p1, PointF p2)
        {
            this.newLines.Add(new Tuple<PointF,PointF>(p1,p2));
            // Invalidate the view => OnPaint Event is raised;
            this.Invalidate();
        }
    }
    

    注意:我没有在 List 操作中添加任何锁定机制。为了防止在使用列表时更改列表,您应该添加一些锁。

    【讨论】:

    • 你能不能给我一些细节或演示,我可以知道更多。
    • 我发现了一个问题:你认为效率提升是由于使用了Bitmap,但我认为效率提升是依赖于新点重绘,而不是所有点。换句话说,我认为那就算不使用BITMAP,只要把新加的点重画一遍,是否能提高效率
    • 如果你画几百行,我发布的方法会更快。所有“旧”线都已绘制。您只需将新行添加到图片并将其绘制到屏幕上。否则,您必须重新绘制所有行(根据您的程序所做的可能有数千行)。
    • 非常感谢,我已经按照你的方法解决了
    • “如果您只添加线条并且不需要删除或修改它们,您也可以将所有线条绘制到位图上,并且在无效时您只将该图像绘制到屏幕上。”--- --------------------------最近我又在想,如何在移动和缩放时保持同样的效率,比如向图像添加新点
    猜你喜欢
    • 2012-08-02
    • 2016-09-24
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多