2013-11-23 62 views
24

我有一个应用程序,其中我有一个UIImageView显示主图像和另一个UIImageView被用作蒙版,该蒙版显示一个透明且不透明的圆形,此圆形可以使用UIPanGestureRecognizer移动,我想知道一个出路,将圆圈内的图像裁剪成新的图像。下面是附带的代码和屏幕截图如何在iOS中的UIImageView中的圈内裁剪图像

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    // create pan gesture 

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self 
                      action:@selector(handlePan:)]; 
    [self.view addGestureRecognizer:pan]; 


    CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
    shapeLayer.path = [[self makeCircleAtLocation:self.view.center radius:100.0] CGPath]; 
    shapeLayer.strokeColor = [[UIColor clearColor] CGColor]; 
    shapeLayer.fillColor = nil; 
    shapeLayer.lineWidth = 3.0; 

    // Add CAShapeLayer to our view 

    [self.view.layer addSublayer:shapeLayer]; 

    // Save this shape layer in a class property for future reference, 
    // namely so we can remove it later if we tap elsewhere on the screen. 

    self.circleLayer = shapeLayer; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 
// Create a UIBezierPath which is a circle at a certain location of a certain radius. 
// This also saves the circle's center and radius to class properties for future reference. 

- (UIBezierPath *)makeCircleAtLocation:(CGPoint)location radius:(CGFloat)radius 
{ 
    self.circleCenter = location; 
    self.circleRadius = radius; 

    UIBezierPath *path = [UIBezierPath bezierPath]; 
    [path addArcWithCenter:self.circleCenter 
        radius:self.circleRadius 
       startAngle:0.0 
        endAngle:M_PI * 2.0 
       clockwise:YES]; 

    return path; 
} 

- (void)handlePan:(UIPanGestureRecognizer *)gesture 
{ 
    static CGPoint oldCenter; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     // If we're starting a pan, make sure we're inside the circle. 
     // So, calculate the distance between the circle's center and 
     // the gesture start location and we'll compare that to the 
     // radius of the circle. 

     CGPoint location = [gesture locationInView:gesture.view]; 
     CGPoint translation = [gesture translationInView:gesture.view]; 
     location.x -= translation.x; 
     location.y -= translation.y; 

     CGFloat x = location.x - self.circleCenter.x; 
     CGFloat y = location.y - self.circleCenter.y; 
     CGFloat distance = sqrtf(x*x + y*y); 

     // If we're outside the circle, cancel the gesture. 
     // If we're inside it, keep track of where the circle was. 


     oldCenter = self.circleCenter; 
    } 
    else if (gesture.state == UIGestureRecognizerStateChanged) 
    { 
     // Let's calculate the new center of the circle by adding the 
     // the translationInView to the old circle center. 

     CGPoint translation = [gesture translationInView:gesture.view]; 
     CGPoint newCenter = CGPointMake(oldCenter.x + translation.x, oldCenter.y + translation.y); 

     // CGPoint newCenter = [gesture locationInView:self.view]; 
     if (newCenter.x < 160) { 
      newCenter.x = 160; 
     } 
     else if (newCenter.x > self.view.frame.size.width - 160) { 
      newCenter.x = self.view.frame.size.width - 160; 
     } 
     if (newCenter.y < 242) { 
      newCenter.y = 242; 
     } 
     else if (newCenter.y > self.view.frame.size.height - imageMain.center.y) { 
      newCenter.y = self.view.frame.size.height - imageMain.center.y; 
     } 

     // Update the path for our CAShapeLayer 

     // self.circleLayer.path = [[self makeCircleAtLocation:newCenter radius:self.circleRadius] CGPath]; 
     imageCircle.center = newCenter; 

    } 
} 

@end 

,其结果是

enter image description here

+0

你想相同的图像,你是在那一刻,看到屏幕上的输出?如果你需要的话,你可以创建一个新的图形上下文,然后将基本图像和'CAShapeLayer'的内容反过来渲染到这个上下文中,并且你将获得所需的输出。你有没有试过这种方法? –

回答

62

要保存蒙面的形象,在搭载iOS 7,你会使用drawViewHierarchyInRect,和早期版本的iOS,你会使用renderInContext。您可能还想用CGImageCreateWithImageInRect裁剪图像。以下我的didTouchUpInsideSaveButton为例。

但我注意到,你显然是通过覆盖图像掩盖。我可能会建议使用UIBezierPath作为图像视图的图层蒙版以及用于绘制圆的CAShapeLayer的基础(假设您在绘制圆时需要边框,如果蒙版是常规(例如一个圆圈),使用UIBezierPath(而不是图片)将其设置为CAShapeLayer可能更为灵活,因为这样您不仅可以用平移手势移动它,还可以将其缩放捏合手势:

enter image description here

下面是一个简单的实现:

// ViewController.m 

#import "ViewController.h" 

@interface ViewController() <UIGestureRecognizerDelegate> 

@property (weak, nonatomic) IBOutlet UIImageView *imageView; 

@property (nonatomic) CGFloat circleRadius; 
@property (nonatomic) CGPoint circleCenter; 

@property (nonatomic, weak) CAShapeLayer *maskLayer; 
@property (nonatomic, weak) CAShapeLayer *circleLayer; 

@property (nonatomic, weak) UIPinchGestureRecognizer *pinch; 
@property (nonatomic, weak) UIPanGestureRecognizer *pan; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create layer mask for the image 

    CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
    self.imageView.layer.mask = maskLayer; 
    self.maskLayer = maskLayer; 

    // create shape layer for circle we'll draw on top of image (the boundary of the circle) 

    CAShapeLayer *circleLayer = [CAShapeLayer layer]; 
    circleLayer.lineWidth = 3.0; 
    circleLayer.fillColor = [[UIColor clearColor] CGColor]; 
    circleLayer.strokeColor = [[UIColor blackColor] CGColor]; 
    [self.imageView.layer addSublayer:circleLayer]; 
    self.circleLayer = circleLayer; 

    // create circle path 

    [self updateCirclePathAtLocation:CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0) radius:self.view.bounds.size.width * 0.30]; 

    // create pan gesture 

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    pan.delegate = self; 
    [self.imageView addGestureRecognizer:pan]; 
    self.imageView.userInteractionEnabled = YES; 
    self.pan = pan; 

    // create pan gesture 

    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; 
    pinch.delegate = self; 
    [self.view addGestureRecognizer:pinch]; 
    self.pinch = pinch; 
} 

- (void)updateCirclePathAtLocation:(CGPoint)location radius:(CGFloat)radius 
{ 
    self.circleCenter = location; 
    self.circleRadius = radius; 

    UIBezierPath *path = [UIBezierPath bezierPath]; 
    [path addArcWithCenter:self.circleCenter 
        radius:self.circleRadius 
       startAngle:0.0 
        endAngle:M_PI * 2.0 
       clockwise:YES]; 

    self.maskLayer.path = [path CGPath]; 
    self.circleLayer.path = [path CGPath]; 
} 

- (IBAction)didTouchUpInsideSaveButton:(id)sender 
{ 
    NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
    NSString *path = [documentsPath stringByAppendingPathComponent:@"image.png"]; 

    CGFloat scale = [[self.imageView.window screen] scale]; 
    CGFloat radius = self.circleRadius * scale; 
    CGPoint center = CGPointMake(self.circleCenter.x * scale, self.circleCenter.y * scale); 

    CGRect frame = CGRectMake(center.x - radius, 
           center.y - radius, 
           radius * 2.0, 
           radius * 2.0); 

    // temporarily remove the circleLayer 

    CALayer *circleLayer = self.circleLayer; 
    [self.circleLayer removeFromSuperlayer]; 

    // render the clipped image 

    UIGraphicsBeginImageContextWithOptions(self.imageView.frame.size, NO, 0.0); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    if ([self.imageView respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) 
    { 
     // if iOS 7, just draw it 

     [self.imageView drawViewHierarchyInRect:self.imageView.bounds afterScreenUpdates:YES]; 
    } 
    else 
    { 
     // if pre iOS 7, manually clip it 

     CGContextAddArc(context, self.circleCenter.x, self.circleCenter.y, self.circleRadius, 0, M_PI * 2.0, YES); 
     CGContextClip(context); 
     [self.imageView.layer renderInContext:context]; 
    } 

    // capture the image and close the context 

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    // add the circleLayer back 

    [self.imageView.layer addSublayer:circleLayer]; 

    // crop the image 

    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], frame); 
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; 

    // save the image 

    NSData *data = UIImagePNGRepresentation(croppedImage); 
    [data writeToFile:path atomically:YES]; 

    // tell the user we're done 

    [[[UIAlertView alloc] initWithTitle:nil message:@"Saved" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show]; 
} 


#pragma mark - Gesture recognizers 

- (void)handlePan:(UIPanGestureRecognizer *)gesture 
{ 
    static CGPoint oldCenter; 
    CGPoint tranlation = [gesture translationInView:gesture.view]; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     oldCenter = self.circleCenter; 
    } 

    CGPoint newCenter = CGPointMake(oldCenter.x + tranlation.x, oldCenter.y + tranlation.y); 

    [self updateCirclePathAtLocation:newCenter radius:self.circleRadius]; 
} 

- (void)handlePinch:(UIPinchGestureRecognizer *)gesture 
{ 
    static CGFloat oldRadius; 
    CGFloat scale = [gesture scale]; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     oldRadius = self.circleRadius; 
    } 

    CGFloat newRadius = oldRadius * scale; 

    [self updateCirclePathAtLocation:self.circleCenter radius:newRadius]; 
} 


#pragma mark - UIGestureRecognizerDelegate 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    if ((gestureRecognizer == self.pan && otherGestureRecognizer == self.pinch) || 
     (gestureRecognizer == self.pinch && otherGestureRecognizer == self.pan)) 
    { 
     return YES; 
    } 

    return NO; 
} 

@end 

如果您不想在圆圈周围绘制边框,则更容易,因为您可以拉取与circleLayer相关的任何内容。重用与广场

+0

完美,你是伟大的人! :)谢谢我想给予atleast 10投票ups :) –

+2

@vishal我看到你想出了如何将你的手势限制与上面的代码结合起来。那很棒!尽管如此,编辑我的答案以包含您的代码被拒绝,因为我们不应该对其他人的答案进行实质性编辑:但是,如果您愿意,可随时向您发布另一个“答案”,以表明您的最终解决方案。 – Rob

+0

多数民众赞成在罚款我不知道,谢谢:) –

2
#import "ViewController.h" 

@interface ViewController() 


@property (weak, nonatomic) IBOutlet UIImageView *imageView; 
@property (weak, nonatomic) IBOutlet UIImageView *crppedImageView; 


@property (nonatomic) CGFloat circleRadius; 
@property (nonatomic) CGPoint circleCenter; 

@property (nonatomic, weak) CAShapeLayer *maskLayer; 
@property (nonatomic, weak) CAShapeLayer *maskSubLayer; 
@property (nonatomic, weak) CAShapeLayer *circleLayer; 

@property (nonatomic, weak) UIPinchGestureRecognizer *pinch; 
@property (nonatomic, weak) UIPanGestureRecognizer *pan; 


@end 

@implementation ViewController 


- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

// create layer mask for the image 

CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
CGRect maskRect = self.imageView.frame; 

// Create a path with the rectangle in it. 
CGPathRef path = CGPathCreateWithRect(maskRect, NULL); 

     // Set the path to the mask layer. 
     maskLayer.path = path; 

    // maskLayer.fillRule = kCAFillRuleEvenOdd; 
    // maskLayer.fillColor = [UIColor blueColor].CGColor; 
    // maskLayer.opacity = 0.5; 

self.imageView.layer.mask = maskLayer; 
self.maskLayer = maskLayer; 

CAShapeLayer *maskLayer1 = [CAShapeLayer layer]; 
CGRect maskRect1 = self.imageView.frame; 

// Create a path with the rectangle in it. 
CGPathRef path1 = CGPathCreateWithRect(maskRect1, NULL); 

// Set the path to the mask layer. 
maskLayer1.path = path1; 

[self.imageView.layer.mask addSublayer:maskLayer1]; 
self.maskSubLayer = maskLayer1; 


// create shape layer for circle we'll draw on top of image (the boundary of the circle) 

CAShapeLayer *circleLayer = [CAShapeLayer layer]; 
circleLayer.lineWidth = 3.0; 
circleLayer.fillColor = [[UIColor blueColor] CGColor]; 
circleLayer.fillRule = kCAFillRuleEvenOdd; 
circleLayer.opacity = 0.5; 
circleLayer.strokeColor = [[UIColor blackColor] CGColor]; 
[self.imageView.layer addSublayer:circleLayer]; 
self.circleLayer = circleLayer; 

// create circle path 

[self updateCirclePathAtLocation:CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0) radius:self.view.bounds.size.width * 0.30]; 

// create pan gesture 

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
pan.delegate = self; 
[self.imageView addGestureRecognizer:pan]; 
self.imageView.userInteractionEnabled = YES; 
self.pan = pan; 

// create pan gesture 

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; 
pinch.delegate = self; 
[self.view addGestureRecognizer:pinch]; 
self.pinch = pinch; 
} 

    - (void)updateCirclePathAtLocation:(CGPoint)location radius:(CGFloat)radius 
    { 
self.circleCenter = location; 
self.circleRadius = radius; 

UIBezierPath *path = [UIBezierPath bezierPath]; 
[path addArcWithCenter:self.circleCenter 
       radius:self.circleRadius 
      startAngle:0.0 
       endAngle:M_PI * 2.0 
      clockwise:YES]; 

UIBezierPath *path1 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.imageView.bounds.size.width, self.imageView.bounds.size.height) cornerRadius:0]; 
[path1 appendPath:path]; 
[path1 setUsesEvenOddFillRule:YES]; 


self.maskSubLayer.path = [path1 CGPath]; 
    self.circleLayer.path = [path1 CGPath]; 

} 

    - (IBAction)didTouchUpInsideSaveButton:(id)sender 
    { 
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
NSString *path = [documentsPath stringByAppendingPathComponent:@"image.png"]; 

CGFloat scale = [[self.imageView.window screen] scale]; 
CGFloat radius = self.circleRadius * scale; 
CGPoint center = CGPointMake(self.circleCenter.x * scale, self.circleCenter.y * scale); 

CGRect frame = CGRectMake(center.x - radius, 
          center.y - radius, 
          radius * 2.0, 
          radius * 2.0); 

// temporarily remove the circleLayer 

CALayer *circleLayer = self.circleLayer; 
[self.circleLayer removeFromSuperlayer]; 

// render the clipped image 

UIGraphicsBeginImageContextWithOptions(self.imageView.frame.size, NO, 0.0); 
CGContextRef context = UIGraphicsGetCurrentContext(); 
if ([self.imageView respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) 
{ 
    // if iOS 7, just draw it 

    [self.imageView drawViewHierarchyInRect:self.imageView.bounds afterScreenUpdates:YES]; 
} 
else 
{ 
    // if pre iOS 7, manually clip it 

    CGContextAddArc(context, self.circleCenter.x, self.circleCenter.y, self.circleRadius, 0, M_PI * 2.0, YES); 
    CGContextClip(context); 
    [self.imageView.layer renderInContext:context]; 
} 

// capture the image and close the context 

UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

// add the circleLayer back 

[self.imageView.layer addSublayer:circleLayer]; 

// crop the image 

CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], frame); 
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; 

_crppedImageView.layer.cornerRadius = _crppedImageView.frame.size.height /2; 
_crppedImageView.layer.masksToBounds = YES; 
_crppedImageView.layer.borderWidth = 0; 
self.crppedImageView.image = croppedImage; 
// save the image 

NSData *data = UIImagePNGRepresentation(croppedImage); 
[data writeToFile:path atomically:YES]; 

// tell the user we're done 

[[[UIAlertView alloc] initWithTitle:nil message:@"Saved" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show]; 
} 


    #pragma mark - Gesture recognizers 

     - (void)handlePan:(UIPanGestureRecognizer *)gesture 
{ 
static CGPoint oldCenter; 
CGPoint tranlation = [gesture translationInView:gesture.view]; 

if (gesture.state == UIGestureRecognizerStateBegan) 
{ 
    oldCenter = self.circleCenter; 
} 

CGPoint newCenter = CGPointMake(oldCenter.x + tranlation.x, oldCenter.y + tranlation.y); 

[self updateCirclePathAtLocation:newCenter radius:self.circleRadius]; 
} 

    - (void)handlePinch:(UIPinchGestureRecognizer *)gesture 
{ 
static CGFloat oldRadius; 
CGFloat scale = [gesture scale]; 

if (gesture.state == UIGestureRecognizerStateBegan) 
{ 
    oldRadius = self.circleRadius; 
} 

CGFloat newRadius = oldRadius * scale; 

[self updateCirclePathAtLocation:self.circleCenter radius:newRadius]; 
} 


#pragma mark - UIGestureRecognizerDelegate 

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
    { 
     if ((gestureRecognizer == self.pan && otherGestureRecognizer == self.pinch) || 
    (gestureRecognizer == self.pinch && otherGestureRecognizer == self.pan)) 
{ 
    return YES; 
} 

return NO; 
} 

    - (void)didReceiveMemoryWarning { 
[super didReceiveMemoryWarning]; 
// Dispose of any resources that can be recreated. 
} 

    @end 
+0

如何裁剪椭圆形脸形图像物镜c?在此代码中... –

4

相同的代码,它可能是其他有用的。

#import "ViewController.h" 

@interface ViewController() <UIGestureRecognizerDelegate> 

@property (weak, nonatomic) IBOutlet UIImageView *imageView; 

@property (nonatomic) CGFloat circleRadius; 
@property (nonatomic) CGPoint circleCenter; 
@property (nonatomic) CGRect frame; 


@property (nonatomic, weak) CAShapeLayer *maskLayer; 
@property (nonatomic, weak) CAShapeLayer *circleLayer; 

@property (nonatomic, weak) UIPinchGestureRecognizer *pinch; 
@property (nonatomic, weak) UIPanGestureRecognizer *pan; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create layer mask for the image 

    CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
    self.imageView.layer.mask = maskLayer; 
    self.maskLayer = maskLayer; 

    // create shape layer for circle we'll draw on top of image (the boundary of the circle) 

    CAShapeLayer *circleLayer = [CAShapeLayer layer]; 
    circleLayer.lineWidth = 3.0; 
    circleLayer.fillColor = [[UIColor clearColor] CGColor]; 
    circleLayer.strokeColor = [[UIColor blackColor] CGColor]; 
    [self.imageView.layer addSublayer:circleLayer]; 
    self.circleLayer = circleLayer; 

    // create circle path 

    [self updateCirclePathAtLocation:CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0) radius:self.view.bounds.size.width * 0.30]; 

    // create pan gesture 

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    pan.delegate = self; 
    [self.imageView addGestureRecognizer:pan]; 
    self.imageView.userInteractionEnabled = YES; 
    self.pan = pan; 

    // create pan gesture 

    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; 
    pinch.delegate = self; 
    [self.view addGestureRecognizer:pinch]; 
    self.pinch = pinch; 
} 

- (void)updateCirclePathAtLocation:(CGPoint)location radius:(CGFloat)radius 
{ 
    self.circleCenter = location; 
    self.circleRadius = radius; 
    self.frame =CGRectMake(self.circleCenter.x/2, self.circleCenter.y/2, self.circleRadius, self.circleRadius); 
    UIBezierPath *path =  [UIBezierPath bezierPathWithRoundedRect:self.frame cornerRadius:0]; 
// [path addArcWithCenter:self.circleCenter 
//     radius:self.circleRadius 
//    startAngle:0.0 
//     endAngle:M_PI * 2.0 
//     clockwise:YES]; 


    self.maskLayer.path = [path CGPath]; 
    self.circleLayer.path = [path CGPath]; 
} 

- (IBAction)didTouchUpInsideSaveButton:(id)sender 
{ 
    NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
    NSString *path = [documentsPath stringByAppendingPathComponent:@"image.png"]; 

    CGFloat scale = [[self.imageView.window screen] scale]; 

    CGRect frame = CGRectMake(self.frame.origin.x *scale, 
           self.frame.origin.y *scale, 
           self.frame.size.width*scale, 
           self.frame.size.width*scale); 

    // temporarily remove the circleLayer 

    CALayer *circleLayer = self.circleLayer; 
    [self.circleLayer removeFromSuperlayer]; 

    // render the clipped image 

    UIGraphicsBeginImageContextWithOptions(self.imageView.frame.size, NO, 0.0); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    if ([self.imageView respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) 
    { 
     // if iOS 7, just draw it 

     [self.imageView drawViewHierarchyInRect:self.imageView.bounds afterScreenUpdates:YES]; 
    } 
    else 
    { 
     // if pre iOS 7, manually clip it 

     CGContextAddRect(context, self.frame); 
     CGContextClip(context); 
     [self.imageView.layer renderInContext:context]; 
    } 

    // capture the image and close the context 

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    // add the circleLayer back 

    [self.imageView.layer addSublayer:circleLayer]; 

    // crop the image 
    NSLog(@"circle fram %@",NSStringFromCGRect(frame)); 
    NSLog(@"self fram %@",NSStringFromCGRect(self.frame)); 

    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], frame); 
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; 

    // save the image 

    NSData *data = UIImagePNGRepresentation(croppedImage); 
    [data writeToFile:path atomically:YES]; 

    // tell the user we're done 

    [[[UIAlertView alloc] initWithTitle:nil message:@"Saved" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show]; 
} 


#pragma mark - Gesture recognizers 

- (void)handlePan:(UIPanGestureRecognizer *)gesture 
{ 
    static CGPoint oldCenter; 
    CGPoint tranlation = [gesture translationInView:gesture.view]; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     oldCenter = self.circleCenter; 
    } 

    CGPoint newCenter = CGPointMake(oldCenter.x + tranlation.x, oldCenter.y + tranlation.y); 

    [self updateCirclePathAtLocation:newCenter radius:self.circleRadius]; 
} 

- (void)handlePinch:(UIPinchGestureRecognizer *)gesture 
{ 
    static CGFloat oldRadius; 
    CGFloat scale = [gesture scale]; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     oldRadius = self.circleRadius; 
    } 

    CGFloat newRadius = oldRadius * scale; 

    [self updateCirclePathAtLocation:self.circleCenter radius:newRadius]; 
} 


#pragma mark - UIGestureRecognizerDelegate 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    if ((gestureRecognizer == self.pan && otherGestureRecognizer == self.pinch) || 
     (gestureRecognizer == self.pinch && otherGestureRecognizer == self.pan)) 
    { 
     return YES; 
    } 

    return NO; 
} 

@end 
+0

如何将其他自定义作物如脸部相关形状在此使用作物图像物镜c –

+0

使用面作为透明覆盖物 – preetam

+0

覆盖物也可以移动和缩放..posable –