0

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

現在、ブラシツールのコードを書いています。前のポイントと現在のポイントを記録し、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();
        }
    }

塗装がはがれないようにする方法を教えてください。

それぞれレイヤー画像でいくつかのキャンバスを作成しようとしました。ただし、ダブルバッファリングされていないため、ちらつきが発生します。

4

1 に答える 1

0

私が驚く主なことは、更新のたびにレイヤー全体をコピーしていることです。影響を受ける領域だけにコピーを制限してみてください。

パフォーマンスとは無関係に、Graphics オブジェクトに対して Dispose を直接呼び出していますが、作成した Brush オブジェクトと Pen オブジェクトは破棄していません。usingブロックの何が悪いの?

于 2012-04-03T05:56:45.553 に答える