2013-08-12 69 views
5

Tôi đang làm việc trên một ứng dụng vẽ nhỏ, có yêu cầu cơ bản về hỗ trợ phóng to/thu nhỏ. Tôi có hai vấn đề chính:Vẽ trên chế độ xem có thể thu phóng

  1. Vẽ không xuất hiện rõ nét và rõ ràng, khi chế độ xem được thu nhỏ/chuyển đổi. Có cách tiếp cận tốt hơn không, hoặc có cách nào để cải thiện bản vẽ khi chế độ xem được thu phóng không?

  2. Hiệu suất bản vẽ chậm, khi vẽ trên canvas 1200 x 1200 pixel (trên iPhone). Bất kỳ cơ hội nào tôi có thể cải thiện nó cho kích thước canvas lớn?

Zooming Code:

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

Vẽ Mã

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

Trả lời

4

Đây là một vấn đề khá phức tạp, mà tôi đã đấu tranh rất nhiều với.

Tôi đã chuyển đổi bản vẽ thành vectơ.

  1. vẽ tất cả các dòng trong một lớp, vẽ tất cả các dòng trong một lớp khác.
  2. Chuyển đổi các bản vẽ dòng để Vector, sử dụng potrace (http://potrace.sourceforge.net/)
  3. vẽ vector sử dụng SVGKit (https://github.com/SVGKit/SVGKit) và ẩn lớp rút ra trong 1)

Nó đang làm việc khá tốt và khá nhanh, nhưng nó đòi hỏi rất nhiều công việc. Chúng tôi có một ứng dụng trong công ty áp dụng kỹ thuật này:

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

Nếu vấn đề duy nhất của bạn là hiệu suất, hãy thử xem CATiledLayer. (cũng được sử dụng trong ứng dụng được đề cập ở trên). Nó sẽ tăng hiệu suất rất nhiều (Bạn có thể tìm thấy một hướng dẫn khá tốt ở đây http://www.cimgf.com/2011/03/01/subduing-catiledlayer/).

Chúc may mắn! :)

+0

Thật vậy, nó trông giống như rất nhiều công việc, và tôi tự hỏi những gì loại hiệu suất (về cả thời gian và fps) bạn đang nhận được trong ứng dụng sơn của bạn? – Mustafa

+0

Việc truy tìm khá tốn thời gian (vài giây), bản vẽ là mặt khác rất nhanh. Chiến lược của chúng tôi là cho phép người dùng vẽ mà không cần truy tìm, cho đến khi người dùng chọn một công cụ khác bắt đầu thu phóng. Sau đó, chúng tôi hiển thị một spinner trong khi chúng tôi thực hiện truy tìm. – EsbenB

0

Trước hết bạn đang chuyển đổi Xem đây không phải là cách tốt hơn để thu phóng. Chuyển đổi có thể chỉ sử dụng để tăng hoặc giảm kích thước của UIVew Để phóng to, bạn có thể d điều này.

1) get vận pic của màn hình bằng cách sử dụng mã này

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) sau đó đặt nó trên một số UIImageView và sau đó thực hiện Zomming trên hình ảnh này

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) sau đó một lần nữa Set thu nhỏ hình ảnh trên nền của uiView

công trình này hoàn hảo cho tôi hy vọng điều này cũng sẽ phù hợp với bạn

+0

Cách tiếp cận này sẽ phóng to hình ảnh bằng cách sử dụng kỹ thuật tương tự như kỹ thuật mà OP đang sử dụng. Bạn sẽ KHÔNG nhận được hình ảnh sắc nét và rõ ràng bằng cách đơn giản là phóng to/chuyển đổi tỷ lệ hình ảnh. – EsbenB