2016-12-27 17 views
-1

GDI +の効率について質問がありました。 いくつかの変数とメソッド は以下のようにあります など1.Points、(例えばXYZとして座標点を表す。)、等B、C、D、E、更新移動マウス

2使用CMD1名前付きリスト、この方法では、

3.Paint法スレッドによって行例えばF、G、H、Iのような新たな点、一定の付加のため

4.Threadに接続された点のセットポイントを追加します、Jなど

ペイントメソッドでは、g.DrawLine()を使用してaとb、c、d、eをリンクします。 スレッドでは、新しいポイントを追加すると、コンポーネントを更新するためにinvalidを呼び出します。 私の質問はますますポイントが増え、どのように高効率を維持して再描画できるのですか?

再描画することから始めることはありません。

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 

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 

AddPointを呼び出しますスレッドが、B、C、D、Eのポイントを追加し、更新するために、無効なメソッドを使用するために、私は、無効呼び出すとき"For Each cmd in Cmd1 In Cmd1s"はそれぞれA点から始まるので、点がますます増えると、どのように高効率を維持して再描画するのかをA点から再描画することはできません。

答えて

1

それはあなたが正確にやりたいことによって異なります。

あなたが現在使用している可能性があります。各無効化で、すべての行を再描画します。描画品質とCPUによっては、線を多かれ少なかれ描くことができますが、少なくとも10行/ msを描画することが可能です。

行を追加して削除または変更する必要がない場合は、すべての行をビットマップに描画し、無効にするとそのイメージのみを画面に描画することもできます。これにより、追加されたときに新しい線を画像に描画するだけで済みます。この方法の問題は、領域をズームまたはパンする場合、または線を削除したい場合は、完全な再描画が必要なことです。

開始点として、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(); 
    } 
} 

注:私はリスト操作に任意の​​ロック機構を追加していません。リストの使用中に変更が行われないようにするには、いくつかのロックを追加する必要があります。

+0

あなたはいくつかの詳細やデモを表示できますか?もっと知ることができます。 – xuyunhai

+0

ありがとう、私は注意深くそれを読むでしょう。 – xuyunhai

+0

私は問題を発見しました: あなたは効率改善がビットマップの使用によるものだと思いますが、私は効率改善が新しいポイントの再描画に依存していると思っています。言い換えれば、新しく追加されたポイントを再描画する唯一の方法であれば、BITMAPを使用して効率を向上させることができます。 – xuyunhai

関連する問題