我遇到了一个有关GDI 效率的问题。有几个变量和方法 如下:1.点,例如A(表示坐标点,例如X Y Z),B,C,D,E等。
2名为CMD1的列表,用于添加线程
的点3. paint方法,在此方法中,连接到该行的点集
4.不断增加新点的线程,例如f,g,h,i,j等。
在油漆方法中,我使用g.drawline()链接a和b,c,d,e。在线程中,当我添加新点时,我将无效刷新组件。所以我的问题是,要点越来越多,我如何保持高效率并重新绘制,
不要从A点开始到re drawline。
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时,每个CMD为CMD1中的CMD1在CMD1中的CMD1"将从一个点开始,因此,当要点变得越来越高时,我如何保持高效率,重新绘制,不要从一个点开始到drawline
这取决于您要做什么。
一种可能性是您当前正在使用的一种。在每个无效的情况下,您重新绘制了所有行。根据图形质量和CPU,您可以绘制或多或少的线条,但应该每毫秒至少绘制10行。
如果您仅添加行而无需删除或修改它们,则还可以将所有行绘制到位图,而在无效的情况下,您只将该图像绘制到屏幕上。通过此,您只需要在添加图片时将新线条绘制到图片中。此方法的问题是,如果要缩放或泛该区域,或者要删除行。
作为起点,请参见Graphics.fromimage(...)方法。使用PixelFormat格式32BPPARGB以最佳性能。
编辑:
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();
}
}
注意:我没有在列表操作中添加任何锁定机制。为了防止使用列表时更改列表时,您应该添加一些锁。