2012-04-02 4 views
0

내 대학 프로젝트에 C와 같은 포토샵 응용 프로그램을 만들려는 임 # 지금까지 필자는 canvas라는 사용자 정의 패널을 작성하고 canvasBuffer를 그릴 paint 메소드를 오버로드했습니다. 이 프로젝트의 페인트는 예리합니다. 이미지의 다양한 레이어를 저장하는 클래스 PaintSharpFile이 있습니다. 캔버스 컨트롤에서 나는 선택된 투명 배경을 그린 다음 페인트 선명한 파일의 레이어를 canvasBuffer에 그립니다. 마침내이 버퍼를 페인트합니다 (이중 버퍼링).버퍼에 드로잉 최적화 C#

이제 브러시 도구의 코드를 작성하고 있습니다. 이전 및 현재 점을 기록한 다음 canvasBuffer 자체에서 Bresenham의 선 알고리즘을 사용하여 두 점 사이에 일련의 원을 그립니다. 이것은 빠르고 잘 작동하는 것 같습니다.

이제 브러시 도구가 선택된 활성 레이어에서 작동 할 것이므로 레이어의 버퍼에 점을 그리려고했습니다. 그런 다음 모든 레이어의 버퍼 canvasBuffer를 그렸습니다. 이렇게하면 도면이 매우 느려집니다.

여기

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

은 어떻게 중지 할 가르쳐주세요 버퍼에 그림 그리기

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

의 코드가요 보온재에서 페인트.

저는 레이어 이미지로 여러 캔버스를 만들려고했습니다. 그러나 이중 버퍼링이 없으므로 깜박임이 발생합니다.

답변

0

나에게 중요한 것은 모든 업데이트마다 전체 레이어를 복사한다는 것입니다. 영향을받는 영역으로 복사를 제한하십시오.

성능과 관련이 없으면 Graphics 객체에서 직접 Dispose를 호출하지만 사용자가 만든 Brush 및 Pen 객체는 삭제하지 말아야합니다. using 블록의 문제점은 무엇입니까?

+0

감사합니다. 방금 구문 문을 사용하는 것에 대해 읽었습니다. 그러면 사각형의 작은 부분을 업데이트하려고 시도합니다. 하지만 이것에 대해 살펴 보시겠습니까? 드로잉 응용 프로그램의 개념을 의미합니다. –

+0

그리기 응용 프로그램을 작성한 적이 없지만 GDI +를 둘러싼 래퍼 인 System.Drawing 네임 스페이스를 사용하면 최상의 성능을 얻지 못할 수도 있습니다. 비트 맵 조작을 직접 목표로하는 드로잉 라이브러리가 더 좋을 수도 있습니다. 너무 많은 코드를 작성하기 전에 고려해야 할 몇 가지 사항은 실행 취소/다시 실행 버퍼를 구현하는 방법과 사용자가 선택한 그리기 도구에 대한 세부 정보를 저장하는 위치입니다. –

+0

Andrew Kennan, 예. GDI +를 드로잉에 사용했으며 원하는 성능을주지 못했습니다. 스트로크 저장 비트 맵의 ​​일부 배열 및 FIFO 스택을 사용하여 실행 취소 및 다시 실행 버퍼를 생각했습니다. http://stackoverflow.com/questions/10126862/optimize-drawing-for-paint-application-c-sharp 내가 제안한 것을 수행하여 최적화를 시도했습니다. 영향을받는 부분 만 그리기. 만약 내가 캔버스 버퍼에 직접 그릴 괜찮아 알파없이. 그러나 레이어링 시스템과 알파 컬러 드로잉 때문에 성능이 현저히 떨어졌습니다. –