优化绘图油漆应用程序C#(Optimize drawing for paint applicatio

2019-09-16 12:33发布

我使用C#进行油漆项目,如Photoshop。 我已经使用了GDI +的绘图。 可悲的是我不能发布的屏幕截图的Cuz所需的声誉点。 编辑:好吧,我得到了足够的代表处上传照片。

使用鼠标,我的画滞后画笔的大小增加时。 我有被吸引到画布面板canvasBuffer

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

这是当任何绘画做会发生什么。

  1. 我存储鼠标拖动事件的点的列表。
  2. 我绘制一系列点从圆形到b点与所记录的点作为其中心来画一条平滑线
  3. 这幅画被存储在层类招列表中的位图来完成。 此图也与CompositingMode.SourceCopy努力执行阿尔法值图纸
  4. 我有一个layerBuffer存储层的最终图像。 我通过使用SourceCopy兼容模式透明色的绘图结算失败中汲取受中风这一layerBuffer更改,然后绘制位图使用SourceOver招名单
  5. 由于分层系统我实现,我画的所有层缓存到pictureBuffer。 此图片缓冲器终于吸引到canvasBuffer与缩放转换。

注:在画布缓冲的患处以相同的方式层缓存,即通过清除患部,然后再返回重绘画面缓冲区的全部患部进行。 如果我不清除以前的图纸,与阿尔法值绘制不按预期工作。

请帮我优化这个代码或建议一些新的方法来提高性能,降低延迟,同时用鼠标画画。 此外,将分离使用线程帮助缓冲区的绘制代码和点的计算和绘图?

下面是代码。

public void PSF_Painted(PSF_PaintEvent e)
    {
        Layer SelectedLayer = psf.Layers[0];//Get selected layer here
        if ((BrushTool)getActiveTool() != null)
        {
            //getting the pen attributes from the brush tool
            BrushTool brushTool = (BrushTool)getActiveTool();
            Pen pen = brushTool.getPen();
            Brush brush = pen.Brush;
            int brushSize = (int)pen.Width;
            //loading points data
            List<Point> recordedPoints = null;
            Point currentPoint = new Point(0, 0);
            Point previousPoint = new Point(0, 0);
            if (e.RecordedPoints != null)
            {
                recordedPoints = e.RecordedPoints;
                if (recordedPoints.Count > 1)
                {
                    currentPoint = recordedPoints[recordedPoints.Count - 1];
                    previousPoint = recordedPoints[recordedPoints.Count - 2];
                }
                else if (recordedPoints.Count == 1)
                {
                    currentPoint = recordedPoints[0];
                    previousPoint = currentPoint;
                }
            }
            if (e.PaintEventType == PSF_PaintEvent.StrokeStarted)
            {
                //Console.WriteLine("StrokeStarted");
                SelectedLayer.Strokes.Add(new Bitmap(SelectedLayer.Width, SelectedLayer.Height));
            }
            else if (e.PaintEventType == PSF_PaintEvent.Painting)
            {
                //Draw the drawing in the bitmap of the layer's stroke data
                using (Graphics g = Graphics.FromImage(SelectedLayer.Strokes[SelectedLayer.Strokes.Count - 1]))
                {
                    List<Point> points = Global.GetPointsOnLine(previousPoint.X, previousPoint.Y, currentPoint.X, currentPoint.Y);
                    for (int i = 0; i < points.Count; i++)
                    {
                        g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
                        if (pen.Width == 1)
                        {
                            g.FillRectangle(brush, new Rectangle(points[i].X, points[i].Y, brushSize, brushSize));
                        }
                        else
                        {
                            g.FillEllipse(brush, new Rectangle(points[i].X, points[i].Y, brushSize, brushSize));
                        }
                        int xt, xb, yt, yb;
                        xt = points[i].X;
                        xb = points[i].X + brushSize;
                        yt = points[i].Y;
                        yb = points[i].Y + brushSize;

                        if (xt < 0) xt = 0;
                        if (xb > psf.Width) xb = SelectedLayer.Width;
                        if (yt < 0) yt = 0;
                        if (yb > psf.Height) yb = SelectedLayer.Height;

                        //Refresh changes to the affected part of the canvas buffer
                        Rectangle affectedRect = new Rectangle(xt, yt, xb - xt, yb - yt);
                        float zf = psf.ZoomFactor;
                        Rectangle canvasAffectedRect = new Rectangle((int)(affectedRect.X * zf), (int)(affectedRect.Y * zf), (int)(affectedRect.Size.Width * zf), (int)(affectedRect.Size.Height * zf));
                        SelectedLayer.invalidateLayerBuffer(affectedRect);
                        invalidateCanvasBuffer(canvasAffectedRect);
                    }
                }
            }
            else if (e.PaintEventType == PSF_PaintEvent.StrokeCompleted)
            {
                //Console.WriteLine("StrokeCompleted");
            }
        }
        this.Invalidate();
    }

Answer 1:

好吧,我发现这种优化的解决方案。 我只记录了分别在距离> 1 /第五刷子的尺寸的点。 我意识到,我并不需要一个非常完美的线条。 因此,在性能线路质量的妥协可以进行交易。



文章来源: Optimize drawing for paint application c#