Question

Im trying to make a photoshop like application for my college project in c# So far I,ve created a custom panel called canvas and overloaded the paint method to draw the canvasBuffer. The project is called paint sharp. I have an Class PaintSharpFile that stores the various layers of the image. On the Canvas control, I draw the checked Transparent Background and then the layers in the paint sharp file on to the canvasBuffer. I finally paint this buffer(Double Buffering).

Now, I am writing the code for the brush tool. I record the previous and the current point and then draw a series of circle between those two points using Bresenham's line algorithm on the canvasBuffer itself. This seems to work fast and fine.

Now since the brush tool will be working on an active layer selected, I tried drawing the points to the buffer of the layer. Then drew all the layer's buffer canvasBuffer. Doing this makes the drawing very slow.

Here's the code

    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();
    }

And here's my onPaint Code

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

Here is the drawing of a picture to the buffer

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();
        }
    }

Please tell me how do I stop the paint from lagging.

I have tried making several canvases each with a layer image. But since it is not double buffered, it causes flickering.

Was it helpful?

Solution

The main thing that jumps out at me is that you're copying the entire layer on every update. Try limiting the copying to just the affected areas.

Unrelated to performance, you're calling Dispose directly on Graphics objects but then not disposing of the Brush and Pen objects you create. What's wrong with using blocks?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top