2013-08-12 99 views
5

我正在研究一個小的繪圖應用程序,它具有支持放大/縮小的基本要求。我有兩個主要問題:在可縮放視圖上繪圖

  1. 當視圖放大/變形時,繪圖不會顯得清晰明瞭。是否有更好的方法,或者有什麼方法可以在視圖縮放時改進繪圖?

  2. 在1200 x 1200磅的畫布上(在iPhone上)繪圖時,繪圖性能很慢。任何機會,我可以改善它的大帆布尺寸?

變焦代碼:

- (void)scale:(UIPinchGestureRecognizer *)gestureRecognizer { 
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer]; 

    UIView *canvas = [gestureRecognizer view]; 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || 
     [gestureRecognizer state] == UIGestureRecognizerStateChanged) { 

     // Calculate the drawing view's size 
     CGSize drawingViewSize = ...; 

     // Calculate the minimum allowed tranform size 
     // Developer's Note: I actually wanted to use the size 1/4th of the view 
     // but self.view.frame.size doesn't return the correct (actual) width and height 
     // It returns these values inverted i.e. width as height, and vice verse. 
     // The reason is that the view appears to be transformed (90 degrees). 
     // Since there's no work-around this, so for now, I'm just using fixed values. 
     CGSize minTranformSize = CGSizeMake(100.0f, 100.0f); 

     if ((minTranformSize.width > drawingViewSize.width) && (minTranformSize.height > drawingViewSize.height)) { 
      minTranformSize = drawingViewSize; 
     } 

     // Transform the view, provided 
     // 1. It won't scale more than the original size of the background image 
     // 2. It won't scale less than the minimum possible transform 
     CGSize transformedSize = CGSizeMake(canvas.frame.size.width * [gestureRecognizer scale], 
              canvas.frame.size.height * [gestureRecognizer scale]); 

     if ((transformedSize.width <= drawingViewSize.width) && (transformedSize.height <= drawingViewSize.height) && 
      (transformedSize.width >= minTranformSize.width) && (transformedSize.height >= minTranformSize.height)) { 

      canvas.transform = CGAffineTransformScale([canvas transform], 
                 [gestureRecognizer scale], 
                 [gestureRecognizer scale]); 
     } 

     [gestureRecognizer setScale:1.0]; 

    } else if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) { 

     // Recenter the container view, if required (piece is smaller than the view and it's not aligned) 
     CGSize viewSize = self.view.bounds.size; 

     if ((canvas.frame.size.width < viewSize.width) || 
      (canvas.frame.size.height < viewSize.height)) { 

      canvas.center = CGPointMake(viewSize.width/2, viewSize.height/2); 
     } 

     // Adjust the x/y coordinates, if required (piece is larger than the view and it's moving outwards from the view) 
     if (((canvas.frame.origin.x > 0) || (canvas.frame.origin.y > 0)) && 
      ((canvas.frame.size.width >= viewSize.width) && (canvas.frame.size.height >= viewSize.height))) { 

      canvas.frame = CGRectMake(0.0, 
             0.0, 
             canvas.frame.size.width, 
             canvas.frame.size.height); 
     } 

     canvas.frame = CGRectIntegral(canvas.frame); 
    } 
} 

繪圖代碼

- (void)draw { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); 

    if (self.fillColor) { 
     [self.fillColor setFill]; 
     [self.path fill]; 
    } 

    if ([self.strokeColor isEqual:[UIColor clearColor]]) { 
     [self.path strokeWithBlendMode:kCGBlendModeClear alpha:1.0]; 

    } else if (self.strokeColor) { 
     [self.strokeColor setStroke]; 
     [self.path stroke]; 
    } 

    CGContextRestoreGState(context); 
} 

回答

4

這是一個非常複雜的問題,我一直在努力了很多用。

我最終將圖紙轉換爲矢量。

  1. 在一個圖層中繪製所有線條,繪製所有線條填充另一個圖層。
  2. 轉換線條畫到矢量,使用potrace(http://potrace.sourceforge.net/
  3. 畫出使用SVGKit (https://github.com/SVGKit/SVGKit)的矢量和隱藏)它工作得很好且相當快速在1繪製的層

,但它需要很多工作。我們在我們公司有一個應用此技術的應用程序:

https://itunes.apple.com/us/app/ideal-paint-hd-mormor/id569450492?mt=8

如果您唯一的問題是性能,請嘗試看看CATiledLayer。 (也用於上面提到的應用程序)。它會極大地提高性能(你可以在這裏找到一個很好的教程http://www.cimgf.com/2011/03/01/subduing-catiledlayer/)。

祝你好運! :)

+0

事實上,它看起來像很多工作,我不知道你在繪畫應用程序中獲得什麼樣的性能(在時間和fps方面)? – Mustafa

+0

跟蹤非常耗時(幾秒鐘),另一方面繪圖非常快。我們的策略是讓用戶不追蹤,直到用戶選擇另一個工具或開始縮放。然後我們在執行跟蹤時顯示一個微調。 – EsbenB

0

首先你正在變換視圖這不是更好的縮放方式。變換可能只用於增加或減小UIVew的大小對於縮放,你可以這樣做。

1)獲得通過使用此代碼

UIGraphicsBeginImageContext(self.drawingView.bounds.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 
//[self.view.layer renderInContext:context]; 
[self.layerContainerView.layer renderInContext:context]; 
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext(); 
[scaleLabel setHidden:FALSE]; 
return screenShot; 

2得到屏幕的PIC),然後把它放在一定的UIImageView然後在此圖像

scrollView.userInteractionEnabled=TRUE; 
self.scrollView.minimumZoomScale = 1.000; 
self.scrollView.maximumZoomScale = 30.0f; 
[self centerScrollViewContents]; 
CGFloat newZoomScale = self.scrollView.zoomScale/1.5f; 
newZoomScale = MAX(newZoomScale, self.scrollView.minimumZoomScale); 
[self.scrollView setZoomScale:newZoomScale animated:YES]; 

3執行Zomming)然後重新設定放大圖片在uiView的背景

這對我來說很完美希望這也適用於你

+0

這種方法將使用類似於OP已經使用的技術來放大圖像。您只需簡單地縮放/縮放圖像即可獲得清晰而清晰的圖像。 – EsbenB