Оптимизировать рисование в буфер C # - PullRequest
0 голосов
/ 02 апреля 2012

Я пытаюсь сделать приложение, похожее на фотошоп, для моего проекта в колледже на c # До сих пор я создал пользовательскую панель с именем canvas и перегрузил метод рисования для рисования canvasBuffer. Проект называется Paint Sharp. У меня есть класс PaintSharpFile, который хранит различные слои изображения. На элементе управления Canvas я рисую отмеченный прозрачный фон, а затем слои в файле с острой краской на canvasBuffer. Я наконец крашу этот буфер (Double Buffering).

Теперь я пишу код для кисти. Я записываю предыдущую и текущую точку, а затем рисую серию окружностей между этими двумя точками, используя алгоритм линий Брезенхэма на самом canvasBuffer. Кажется, это работает быстро и хорошо.

Теперь, когда кисть будет работать с выбранным активным слоем, я попытался нарисовать точки в буфере слоя. Затем нарисовал весь буфер слоя 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();
        }
    }

Пожалуйста, скажите мне, как я могу остановить отставание краски.

Я попытался сделать несколько холстов, каждый с изображением слоя. Но поскольку он не имеет двойной буферизации, он вызывает мерцание.

1 Ответ

0 голосов
/ 03 апреля 2012

Главное, что бросается в глаза, это то, что вы копируете весь слой при каждом обновлении. Попробуйте ограничить копирование только затронутыми областями.

Вне зависимости от производительности вы вызываете Dispose непосредственно для графических объектов, но не избавляетесь от созданных вами объектов Brush и Pen. Что не так с using блоками?

...