如何使用UIBezierPath裁剪图像?

我想从UIBezierpath闭path中获取图像(请参阅图像)。 我使用drawRect方法在UIView上绘制图像,并绘制线条使用drawRect方法。 我怎样才能得到特定的闭path图像? 请帮帮我。 提前致谢。

这个代码用于绘制贝塞尔path。

 UIBezierPath *aPath = [UIBezierPath bezierPath]; for (NSString *pointString in pointArray) { if ([pointArray indexOfObject:pointString] == 0) [aPath moveToPoint:CGPointFromString(pointString)]; else [aPath addLineToPoint:CGPointFromString(pointString)]; } [aPath closePath]; 

在这里输入图像说明

你可以使用shapeLayer 。 就像是,

 UIBezierPath *aPath = [UIBezierPath bezierPath]; for (NSString *pointString in pointArray) { if ([pointArray indexOfObject:pointString] == 0) [aPath moveToPoint:CGPointFromString(pointString)]; else [aPath addLineToPoint:CGPointFromString(pointString)]; } [aPath closePath]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = aPath.CGPath; [view.layer setMask:shapeLayer];//or make it as [imageview.layer setMask:shapeLayer]; //and add imageView as subview of whichever view you want. draw the original image //on the imageview in that case 

为了把它作为一个图像,

 UIGraphicsBeginImageContext(view.bounds.size); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

image应该有相应的图像。

那么,有几件事你必须注意。

  1. 你传递你的UIImageView而不是你的UIView?
  2. 如果你是,你是否启用你的图像视图的触摸处理?
  3. 子类化你的UIImageView,并使用drawrect()来处理你的东西。

如果你只想要图像的一部分(如猫),那么你需要按照UIBezierPath来掩盖你的图像。

更新

以下是一个完整的工作示例,将其更改为您的要求。

ViewController.h:

 @interface ViewController : UIViewController { UIBezierPath *aPath; } @property (nonatomic,retain) NSMutableArray *pathArray; @property (nonatomic,retain) NSMutableDictionary *dic; @property (nonatomic,retain) IBOutlet UIImageView *imgView; @end 

ViewController.m:

 @interface ViewController () - (IBAction)Crop:(id)sender; @end @implementation ViewController @synthesize pathArray,dic,imgView; - (void)viewDidLoad { [super viewDidLoad]; } - (void) setClippingPath:(UIBezierPath *)clippingPath : (UIImageView *)imgView; { NSLog(@"Mask Paths %@",clippingPath); CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.frame = self.imgView.frame; maskLayer.path = [clippingPath CGPath]; maskLayer.fillColor = [[UIColor whiteColor] CGColor]; maskLayer.backgroundColor = [[UIColor clearColor] CGColor]; self.imgView.layer.mask = maskLayer; } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *mytouch=[[touches allObjects] objectAtIndex:0]; self->aPath = [[UIBezierPath alloc]init]; [aPath moveToPoint:[mytouch locationInView:imgView]]; } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *mytouch=[[touches allObjects] objectAtIndex:0]; [aPath addLineToPoint:[mytouch locationInView:imgView ]]; } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { } - (IBAction)Crop:(id)sender { [self setClippingPath:aPath :imgView]; } 

使用这个pod ios-helpers

 - (UIImage *)imageWithStrokeColor: (UIColor *)stroke_color andFillColor: (UIColor *)fill_color { // adjust bounds to account for extra space needed for lineWidth CGFloat width = self.bounds.size.width + self.lineWidth * 2; CGFloat height = self.bounds.size.height + self.lineWidth * 2; CGRect bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, width, height); // create a view to draw the path in UIView *view = [[UIView alloc] initWithFrame:bounds]; // begin graphics context for drawing UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, [[UIScreen mainScreen] scale]); // configure the view to render in the graphics context [view.layer renderInContext:UIGraphicsGetCurrentContext()]; // get reference to the graphics context CGContextRef context = UIGraphicsGetCurrentContext(); // reverse the y-axis to match the opengl coordinate space CGContextScaleCTM(context, 1, -1); CGContextTranslateCTM(context, 0, -view.bounds.size.height); // translate matrix so that path will be centered in bounds CGContextTranslateCTM(context, -(bounds.origin.x - self.lineWidth), -(bounds.origin.y - self.lineWidth)); // stroke color [stroke_color setStroke]; [self stroke]; //fill color [fill_color setFill]; [self fill]; // get an image of the graphics context UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); // end the context UIGraphicsEndImageContext(); return viewImage; } 

如果你在代码中绘制所有东西,只需使用 – addClip ,即:

 UIBezierPath *aPath = [UIBezierPath bezierPath]; for (NSString *pointString in pointArray) { if ([pointArray indexOfObject:pointString] == 0) [aPath moveToPoint:CGPointFromString(pointString)]; else [aPath addLineToPoint:CGPointFromString(pointString)]; } [aPath closePath]; CGContextSaveGState(context); { [aPath addClip]; // draw image [aPath stroke]; } CGContextRestoreGState(context); 

对于Swift试试这个: ZImageCropper

ZImageCropper使用以下的东西作为核心部分:

  • UIBezierPath
  • UITouch事件
  • CAShapeLayer
  • CoreGraphics中

这对我有用…

 UIBezierPath *path = ....//your path CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(nil, frame.size.width, frame.size.height, 8, 4*frame.size.width, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst); CGContextAddPath(context, path.CGPath); CGContextClip(context); CGContextDrawImage(context, frame, image.CGImage); [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; 

iDev的答案非常好,但是如果你需要透明的背景,那么除了UIGraphicsBeginImageContext(view.bounds.size); 你应该使用

 UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 1.0); 

默认情况下,图像上下文是用不透明的== YES创build的,所以你必须把它改为NO。

 // This Work 100% 

– (void)touchesBegan:(NSSet *)碰到事件:(UIEvent *)event {

 mouseSwiped = NO; UITouch *touch = [touches anyObject]; lastPoint = [touch locationInView:self.view]; megView = [[UIImageView alloc]initWithFrame:CGRectMake(lastPoint.x , lastPoint.y , k_POINT_WIDTH , k_POINT_WIDTH )]; //[megView setImage:[UIImage imageNamed:@"b_image22.png"]]; [megView setContentMode:UIViewContentModeScaleToFill]; megView.alpha = 2; //megView.layer.backgroundColor = [UIColor whiteColor].CGColor; //megView.layer.cornerRadius = megView.frame.size.width / 2; megView.clipsToBounds = YES; [self.main_uiview addSubview:megView]; self.bezierPath = [UIBezierPath bezierPath]; [self.bezierPath moveToPoint:lastPoint]; 

}

  // Touchmove method - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { mouseSwiped = YES; UITouch *touch = [touches anyObject]; CGPoint currentPoint = [touch locationInView:self.view]; UIGraphicsBeginImageContext(self.main_uiview.frame.size); [self.bg_imageview.image drawInRect:CGRectMake(0, 0, self.main_uiview.frame.size.width, self.main_uiview.frame.size.height)]; megView.frame = CGRectMake( currentPoint.x - k_POINT_WIDTH/2 , currentPoint.y - k_POINT_WIDTH/2 , k_POINT_WIDTH , k_POINT_WIDTH ); CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextStrokePath(UIGraphicsGetCurrentContext()); CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red,green ,blue, 0.20); CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy); self.bg_imageview.image = UIGraphicsGetImageFromCurrentImageContext(); [self.bg_imageview setAlpha:opacity]; UIGraphicsEndImageContext(); lastPoint = currentPoint; [self.bezierPath addLineToPoint:lastPoint]; 

}

  // TouchEnd Method - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 

{

 [megView removeFromSuperview]; 

}

  // Image Crop Method -(UIImage *)croppedImage { UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [self.bezierPath closePath]; CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 0.0); _b_image = self.bg_imageview.image; CGSize imageSize = _b_image.size; CGRect imageRect = CGRectMake(0, 0, imageSize.width, imageSize.height); UIGraphicsBeginImageContextWithOptions(imageSize, NO, [[UIScreen mainScreen] scale]); [self.bezierPath addClip]; [_b_image drawInRect:imageRect]; UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return croppedImage; 

}