优化图纸的绘图应用程序C# [英] Optimize drawing for paint application c#

查看:404
本文介绍了优化图纸的绘图应用程序C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

 保护覆盖无效的OnPaint(PaintEventArgs的E)$ B $一个canvasBuffer b {
如果(canvasBuffer!= NULL)
{使用
(图形G = e.Graphics)
{
g.DrawImage(canvasBuffer,e.ClipRectangle, e.ClipRectangle,GraphicsUnit.Pixel);
}
}
}



这是发生在什么任何绘画完成。




  1. 我存储鼠标拖动事件点的名单。

  2. 我画的一系列点的圆,以点b与记录点为中心来画一条平滑线

  3. 本图是在存储在笔划的列表的位图进行层类。
    此图也与CompositingMode.SourceCopy努力执行Alpha值图

  4. 我有一个layerBuffer存储层的最终图像。我用SourceCopy兼容模式,然后绘制位图使用SourceOver

  5. 由于招的列表,并附有透明色的图画清除失败中汲取受中风此layerBuffer的变化我采取分层系统,我绘制所有层缓冲器到pictureBuffer。
    这张照片缓冲区终于吸引到canvasBuffer与缩放转换



请注意:画布缓冲的患处以相同的方式如通过清除患部,然后再返回重绘图片缓冲器的整个患部即该层缓冲区完成。
如果我没有清除以前的图纸,阿尔法值绘制的不正常工作。



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



下面是代码。

 公共无效PSF_Painted(PSF_PaintEvent E)
{
层SelectedLayer = psf.Layers [0]; //获取选中图层这里
如果((brushTool)getActiveTool()!= NULL)
{
从画笔工具
brushTool brushTool = //获取笔属性(brushTool )getActiveTool();
喷喷= brushTool.getPen();
刷刷= pen.Brush;
INT brushSize =(INT)pen.Width;
//加载点数据
名单,LT;点和GT; recordedPoints = NULL;
点currentPoint =新的点(0,0);
点previousPoint =新的点(0,0);
如果(e.RecordedPoints!= NULL)
{
recordedPoints = e.RecordedPoints;
如果(recordedPoints.Count→1)
{
currentPoint = recordedPoints [recordedPoints.Count - 1];
previousPoint = recordedPoints [recordedPoints.Count - 2];
}
,否则如果(recordedPoints.Count == 1)
{
currentPoint = recordedPoints [0];
previousPoint = currentPoint;
}
}
如果(e.PaintEventType == PSF_PaintEvent.StrokeStarted)
{
//Console.WriteLine(\"StrokeStarted);
SelectedLayer.Strokes.Add(新位图(SelectedLayer.Width,SelectedLayer.Height));
}
,否则如果(e.PaintEventType == PSF_PaintEvent.Painting)
{
//使用绘图层中的笔划数据
的位图(图形G = Graphics.FromImage(SelectedLayer.Strokes [SelectedLayer.Strokes.Count - 1]))
{
名单,LT;点和GT;分= Global.GetPointsOnLine(previousPoint.X,previousPoint.Y,currentPoint.X,currentPoint.Y);
的for(int i = 0; I< points.Count;我++)
{
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
如果(pen.Width == 1)
{
g.FillRectangle(毛笔,新的Rectangle(分[I] .X,点[I] .Y,brushSize,brushSize)) ;
}
,否则
{
g.FillEllipse(毛笔,新的Rectangle(分[I] .X,点[I] .Y,brushSize,brushSize));
}
INT XT,XB,YT,YB;
XT =点[I] .X;
XB =点[I] .X + brushSize;
YT =点[I] .Y;
YB =点[I] .Y + brushSize;

如果(XT℃,)XT = 0;
如果(XB> psf.Width)XB = SelectedLayer.Width;
如果(YT℃,)YT = 0;
如果(YB> psf.Height)YB = SelectedLayer.Height;

//刷新更改画布缓冲区
矩形affectedRect =新的Rectangle患部(XT,YT,XB - XT,YB - YT);
浮动ZF = psf.ZoomFactor;
矩形canvasAffectedRect =新的Rectangle((INT)(affectedRect.X * ZF),(INT)(affectedRect.Y * ZF),(INT)(affectedRect.Size.Width * ZF),(INT)(affectedRect .Size.Height * ZF));
SelectedLayer.invalidateLayerBuffer(affectedRect);
invalidateCanvasBuffer(canvasAffectedRect);
}
}
}
,否则如果(e.PaintEventType == PSF_PaintEvent.StrokeCompleted)
{
//Console.WriteLine(\"StrokeCompleted) ;
}
}
this.Invalidate();
}


解决方案

好吧,我找到了解决办法这种优化。
我只记录了是在距离> 1/5的画笔大小之分。
我意识到,我并不需要一个非常完美的线条。因此,在对性能的线路的质量的折衷可以进行交易。


I am making a paint project like photoshop using c#. I have used GDI+ for the drawing. Sadly I cannot post the screen shot cuz of the reputation points required. EDIT : Ok i got enough rep to upload a pic.

My drawing using the mouse lags when the brush size increases. I have a canvasBuffer which is drawn to the canvas panel

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

And this is what happens when any painting is done.

  1. I store the list of points of the mouse drag event.
  2. I draw a series of circle from point a to point b with the recorded point as its center to draw a smooth line
  3. This drawing is done on the bitmap stored in the list of strokes in the layer class. This drawing is also done with CompositingMode.SourceCopy to implement alpha value drawings
  4. I have a layerBuffer that stores the final image of the layer. I draw the changes affected by the stroke to this layerBuffer by clearing it with a drawing of a transparent color using SourceCopy Compatibility mode and then draw the bitmaps in the list of strokes using SourceOver
  5. Due to the layering system I am implementing, I draw all the layer buffer to a pictureBuffer. This picture Buffer is finally drawn to the canvasBuffer with scaling transformations.

Note : The affected area of the canvas Buffer is done in the same manner as the layer Buffer i.e by clearing the affected part and redrawing the entire affected part of the picture buffer back again. If I do not clear the previous drawing, drawing with alpha value does not work as expected.

Please help me to optimize this code or suggest some new ways to improve the performance and reduce the lag while drawing using the mouse. Also, would separating the drawing code and the calculation of the points and drawing of the buffers using threads help ?

Here is the code.

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

解决方案

Ok, I found a solution for this optimization. I only recorded the points which were at a distance > 1/5th the size of the brush. I realized that I did not need a very perfect line. Therefore the compromise in the quality of the line for performance can be traded.

这篇关于优化图纸的绘图应用程序C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆