¿Cómo recortar la image usando UIBezierPath?

Quiero get la image desde la UIBezierpath cerrada de UIBezierpath (ver la image). Dibujo la image en UIView usando el método drawRect y también dibujo las líneas están usando el método drawRect . ¿Cómo puedo get la image de ruta cerrada particular? Por favor, ayúdame. Gracias por adelantado.

Este código se usa para dibujar el bezierpath.

 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]; 

introduzca la descripción de la imagen aquí

Puedes usar un shapeLayer para eso. Algo como,

 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 

Para getlo como una image,

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

image debe tener la image correspondiente.

use este 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 centenetworking 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; } 

Bueno, hay un par de cosas que debes tener en count.

  1. ¿Pasas tu UIImageView en lugar de tu UIView?
  2. Si lo está, ¿habilitó su vista de image para el manejo táctil?
  3. Subclass su UIImageView y use drawrect() para manejar esas cosas por usted.

Si desea solo una parte de la image (como el gato), entonces debe submascarar su image de acuerdo con UIBezierPath.

Actualizado

El siguiente es un ejemplo de trabajo completo, cámbielo a sus requisitos.

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]; } 

Si está dibujando todo en el código simplemente use – addClip , es decir:

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

Para Swift testing esto: ZImageCropper

ZImageCropper está utilizando los siguientes elementos como parte central:

  • UIBezierPath
  • Eventos de UITouch
  • CAShapeLayer
  • CoreGraphics

esto funciona para mí …

 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)]; 

La respuesta de iDev es excelente, pero si necesita un background transparente, excepto UIGraphicsBeginImageContext(view.bounds.size); Deberías usar

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

Por defecto, el context de la image se crea con opaque == YES, así que debe cambiarlo a NO.

 // This Work 100% 

– (void) touchesBegan: (NSSet *) toca withEvent: (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(), networking,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; 

}