2012-04-02 12 views
0

私の大学のプロジェクトのようなアプリケーションをCで作成しようとしています。 これまで私はcanvasというカスタムパネルを作成し、canvasBufferを描画するためにpaintメソッドをオーバーロードしました。 プロジェクトは、シャープペンキと呼ばれます。 私は、画像のさまざまなレイヤを格納するクラスPaintSharpFileを持っています。 キャンバスコントロールでは、チェックされた透明な背景を描画してから、ペイントシャープファイルのレイヤーをキャンバスバッファに描画します。私は最終的にこのバッファをペイントします(ダブルバッファリング)。バッファに描画を最適化するC#

今、私はブラシツールのコードを書いています。 前と現在の点を記録し、次にcanvasBuffer自体のBresenhamの線アルゴリズムを使用して、それらの2点の間に一連の円を描画します。これは速くて上手く動作するようです。

ブラシツールが選択されているアクティブなレイヤーで動作しているので、レイヤーのバッファにポイントを描画しようとしました。次に、すべてのレイヤのバッファcanvasBufferを描画します。これにより描画が非常に遅くなります。

は、ここでは、コード

public void PSF_Painted(PSF_PaintEvent e) 
    { 
     Graphics g = null; 
     Bitmap layerBuffer = psf.Layers[0].LayerBuffer;//Get selected layer here 
     g = Graphics.FromImage(layerBuffer); 
     Brush blackBrush = new SolidBrush(Color.Black); 
     Pen blackPen = new Pen(blackBrush); 
     blackPen.Width = 2; 

     List<Point> recordedPoints = e.RecordedPoints; 
     Point currentPoint = new Point(0,0); 
     Point previousPoint = new Point(0, 0); ; 
     if(recordedPoints.Count > 0) 
     { 
      currentPoint = recordedPoints[recordedPoints.Count - 1]; 
      if(recordedPoints.Count == 1) 
      { 
       previousPoint = recordedPoints[0]; 
      } 
      else 
      { 
       previousPoint = recordedPoints[recordedPoints.Count - 2]; 
      } 
     } 

     if (e.PaintEventType == PSF_PaintEvent.Painting) 
     { 
      List<Point> points = Global.GetPointsOnLine(previousPoint.X, previousPoint.Y, currentPoint.X, currentPoint.Y); 
      for (int i = 0; i < points.Count ; i++) 
      { 
       g.FillEllipse(blackBrush, new Rectangle(points[i].X, points[i].Y, (int)blackPen.Width, (int)blackPen.Width)); 
      } 
     } 
     Global.drawToBuffer(canvasBuffer, layerBuffer);//Replaced with redraw the full picture from the List of layer to the canvasBuffer 
     g.Dispose(); 
     this.Invalidate(); 
    } 

そしてここでは、ここに私のOnPaintコード

protected override void OnPaint(PaintEventArgs e) 
    { 
     if (canvasBuffer != null) 
     { 
      Graphics g = e.Graphics; 
      g.DrawImage(canvasBuffer, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel); 
      g.Dispose(); 
     } 
    } 

だのバッファ

public static void drawToBuffer(Bitmap buffer, Bitmap image) 
    { 
     if (image != null && buffer != null) 
     { 
      Graphics g = Graphics.FromImage(buffer); 
      g.DrawImage(image, new Rectangle(0, 0, buffer.Width, buffer.Height)); 
      g.Dispose(); 
     } 
    } 

への画像の描画は、私がどのように停止するかを教えてくださいされます遅れから塗料。

私はレイヤーイメージでそれぞれいくつかのキャンバスを作ってみました。しかし、ダブルバッファではないので、フリッカーが発生します。

答えて

0

私が飛びつく主なことは、すべてのアップデートでレイヤー全体をコピーしていることです。影響を受けるエリアだけにコピーを制限してみてください。

パフォーマンスとは無関係に、Graphicsオブジェクトで直接Disposeを呼び出していますが、作成したBrushオブジェクトやPenオブジェクトを破棄しないでください。 usingブロックで何が問題になっていますか?

+0

ありがとう..私はちょうど使用している文の構文について読んだ。 私は矩形の小さな部分を更新しようとします。 しかし、これはそれについて行く方法ですか?私は描画アプリケーションの概念を意味します。 –

+0

私は描画アプリケーションを書いたことはありませんが、GDI +のラッパーであるSystem.Drawing名前空間を使用すると、最高のパフォーマンスが得られない可能性があります。直接ビットマップ操作を目的とした描画ライブラリが良いかもしれません。あまりにも多くのコードを書く前に検討する価値のあるものは、Undo/Redoバッファを実装する方法と、ユーザーが選択した描画ツールの詳細をどこに保存するのかです。 –

+0

Andrew Kennan、はい私は描くためにGDI +を使用しました。私はいくつかの配列とストロークの格納されたビットマップのFIFOスタックを使用して、元に戻すと再実行のバッファーについて考えています。 私はあなたにこれを見てみたいと思いますhttp://stackoverflow.com/questions/10126862/optimize-drawing-for-paint-application-c-sharp 私はあなたが提案したものを使ってそれを最適化しようとしました影響を受けた部分のみを描画します。もし私がキャンバスバッファに直接描画していて、アルファなしであれば、それは大丈夫です。しかし、レイヤリングシステムとアルファの色の描画のために私はパフォーマンスが賢明に立ち往生しています。 –

関連する問題