Comment recadrer l'image en utilisant UIBezierPath?

Je veux get l'image du path fermé UIBezierpath (voir l'image). Je dessine l'image sur l' UIView utilisant la méthode drawRect et dessine également les lignes en utilisant la méthode drawRect . Comment puis-je get l'image particulière du path fermé? Aidez-moi, s'il vous plaît. Merci d'avance.

Ce code utilisé pour dessiner le bezierpath.

 UIBezierPath *aPath = [UIBezierPath bezierPath]; for (NSSsortingng *pointSsortingng in pointArray) { if ([pointArray indexOfObject:pointSsortingng] == 0) [aPath moveToPoint:CGPointFromSsortingng(pointSsortingng)]; else [aPath addLineToPoint:CGPointFromSsortingng(pointSsortingng)]; } [aPath closePath]; 

entrez la description de l'image ici

Vous pouvez utiliser un shapeLayer pour cela. Quelque chose comme,

 UIBezierPath *aPath = [UIBezierPath bezierPath]; for (NSSsortingng *pointSsortingng in pointArray) { if ([pointArray indexOfObject:pointSsortingng] == 0) [aPath moveToPoint:CGPointFromSsortingng(pointSsortingng)]; else [aPath addLineToPoint:CGPointFromSsortingng(pointSsortingng)]; } [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 

Pour l'get en image,

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

image doit avoir l'image correspondante.

Eh bien, il y a un certain nombre de choses que vous devez prendre en count.

  1. Passez-vous votre UIImageView au lieu de votre UIView?
  2. Si oui, avez-vous activé l'affichage de votre image pour le traitement tactile?
  3. Sous-class votre UIImageView et utilisez drawrect() pour gérer ce truc pour vous.

Si vous ne voulez qu'une partie de l'image (comme le chat), vous devez masquer votre image selon UIBezierPath.

Actualisé

Ce qui suit est un exemple de travail complet, changez-le à vos besoins.

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

utiliser ce 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 masortingx 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; } 

Si vous addClip tout en code, utilisez simplement: addClip , c'est-à-dire:

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

Pour Swift, essayez ceci: ZImageCropper

ZImageCropper utilise les choses suivantes comme partie centrale:

  • UIBezierPath
  • UITouch Events
  • CAShapeLayer
  • CoreGraphics

Cela fonctionne pour moi …

 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 réponse d'iDev est excellente, mais si vous avez besoin d'un fond transparent, alors UIGraphicsBeginImageContext(view.bounds.size); Tu devrais utiliser

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

Par défaut, le context de l'image est créé avec opaque == OUI, donc vous devez le changer en NON.

 // This Work 100% 

– (void) touchesBegan: (NSSet *) touche avecEvent: (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; 

}