在可缩放的视图上绘图

时间:2013-08-12 07:38:35

标签: ios uiview drawing

我正在开发一个小型绘图应用程序,它具有支持放大/缩小的基本要求。我有两个主要问题:

  1. 当缩放/转换视图时,绘图不会显得清晰明朗。是否有更好的方法,或者在缩放视图时是否有办法改善绘图?

  2. 在1200 x 1200点的画布(在iPhone上)绘图时,绘图性能很慢。我有机会为大帆布尺寸改进吗?

  3. 缩放代码:

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

2 个答案:

答案 0 :(得分:5)

这是一个非常复杂的问题,我一直在努力。

我最终将图纸转换为矢量。

  1. 在一个图层中绘制所有线条,在另一个图层中绘制所有填充。
  2. 使用potrace(http://potrace.sourceforge.net/
  3. 将线条图转换为Vector
  4. 使用SVGKit绘制矢量 (https://github.com/SVGKit/SVGKit)并隐藏1)中绘制的图层
  5. 它工作得非常好并且相当快,但它需要大量的工作。我们公司的应用程序采用了这种技术:

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

    如果您唯一的问题是性能,请尝试查看CATiledLayer。 (也用于上面提到的应用程序)。它将极大地提高性能(你可以在这里找到一个非常好的教程http://www.cimgf.com/2011/03/01/subduing-catiledlayer/)。

    祝你好运! :)

答案 1 :(得分:-1)

首先你是转换视图这不是更好的缩放方式。转换可能仅用于增加或减小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)然后将它放在一些UIImageView上,然后在这个图像上执行Zomming

 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)然后再次在uiView的背景上设置缩放图像

这对我来说很完美,希望这对你也有用