2012-04-02 78 views
0

我试图让我的大学项目在c#中的应用程序像一个Photoshop# 到目前为止,我创建了一个名为画布的自定义面板并重载绘制方法来绘制canvasBuffer。 该项目被称为油漆锐利。 我有一个类PaintSharpFile,它存储图像的各个层次。 在画布控件上,我绘制了选中的透明背景,然后将绘制清晰文件中的图层绘制到canvasBuffer上。我终于画这个缓冲区(双缓冲)。优化绘制缓冲区C#

现在,我正在编写画笔工具的代码。 我记录了前一个和当前点,然后在这两个点之间使用Bresenham的线算法在画布缓冲本身上绘制一系列圆。这似乎工作得很快,很好。

现在,由于画笔工具将在选定的活动图层上工作,我尝试将图层绘制到图层的缓冲区。然后绘制所有图层的缓冲区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(); 
     } 
    } 

请告诉我,我该怎么办停止来自落后的油漆。

我已经尝试制作几个画布,每个画布都有一个图层图像。但由于它不是双重缓冲,所以会导致闪烁。

回答

0

跳到我身上的主要原因是您在每次更新时都复制整个图层。尝试限制复制到受影响的区域。

与性能无关,您直接在Graphics对象上调用Dispose,但不处置您创建的Brush和Pen对象。 using块有什么问题?

+0

谢谢..我刚刚阅读了关于使用语句的语法.. 然后我会尝试更新矩形的一小部分。 但是,这是要走的路吗?我的意思是绘图应用程序的概念。 – 2012-04-03 20:23:53

+0

我从来没有写过绘图应用程序,但我怀疑使用System.Drawing命名空间,GDI +的包装,可能不会给你最好的性能。直接针对位图操作的绘图库可能会更好。在编写太多代码之前,一些值得考虑的事情是如何实现撤消/重做缓冲区,以及在哪里存储有关用户所选绘图工具的详细信息? – 2012-04-03 23:37:40

+0

安德鲁凯南,是的,我用GDI +来绘画,它不给我我想要的表演。我通过使用一些存储的笔划位图的数组和FIFO堆来考虑撤消和重做缓冲区。 我想请你看看这个http://stackoverflow.com/questions/10126862/optimize-drawing-for-paint-application-c-sharp 我试着通过做你的建议来优化它并只绘制受影响的部分。如果,我直接在画布缓冲区上绘制,并且没有alpha就好了。但由于分层系统和alpha彩色绘图,我坚持性能明智。 – 2012-04-12 15:35:52