2013-08-12 16 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. すべての線を1つのレイヤに描画し、すべての線を別のレイヤに描画します。
  2. 、それはかなりうまく働いて、かなり高速です(http://potrace.sourceforge.net/
  3. SVGKit (https://github.com/SVGKit/SVGKit)を使用してベクトルを描画し、1に描かれたレイヤーを非表示)potraceを使用して、ベクトルへ

を線画に変換しかし、それは多くの作業を必要とします。この技術を適用する弊社のアプリがあります:

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

唯一の問題がパフォーマンスの場合は、CATiledLayerをご覧ください。 (上記のアプリでも使用されています)。パフォーマンスが大幅に向上します(ここではかなり良いチュートリアルhttp://www.cimgf.com/2011/03/01/subduing-catiledlayer/が見つかります)。

幸運を祈る! :)

+0

実際、多くの作業のように見えますが、ペイントアプリケーションでどんな種類のパフォーマンス(時間とフレームレートの両方で)が得られるのでしょうか? – Mustafa

+0

トレースにはかなりの時間がかかります(数秒)。一方、描画は非常に高速です。私たちの戦略は、ユーザーがズームを開始する別のツールを選択するまで、ユーザーがトレースせずに描画できるようにすることです。次に、トレースを実行しながらスピナーを表示します。 – EsbenB

0

まず、あなたは変態しています。これは、変倍のためのより良い方法ではありません。変換は、UIVewの増減のサイズにのみ使用できます。

1)は、その後、いくつかの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を実行する)このコード

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を使用することにより、画面の写真をゲットする)、再度ズームを設定イメージはuiViewの背景にあります

これは私にとっても最適です。これはあなたにとってもうまくいくと願っています。

+0

この方法では、OPがすでに使用しているのと同様の手法を使用してイメージを拡大表示します。画像をズーム/拡大/縮小するだけで鮮明で鮮明な画像を得ることはできません。 – EsbenB

関連する問題