如何使用UIBezierPath裁剪图像?

时间:2012-10-31 07:33:13

标签: iphone objective-c ios uibezierpath

我想从UIBezierpath封闭路径获取图片(参见图片)。我使用UIView方法在drawRect上绘制图像,并使用drawRect方法绘制线条。 如何获得特定的闭路径图像?请帮我。提前谢谢。

此代码用于绘制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];

enter image description here

8 个答案:

答案 0 :(得分:14)

您可以使用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 :(得分:3)

嗯,有几件事需要注意。

  1. 您是否正在传递UIImageView而不是UIView?
  2. 如果您是,是否启用了图像视图以进行触摸处理?
  3. 对您的UIImageView进行子类化,并使用drawrect()为您处理这些内容。
  4. 如果您只想要图像的一部分(如猫),则需要根据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];
     }
    

答案 2 :(得分:3)

对于 Swift ,请尝试:ZImageCropper

ZImageCropper正在使用以下内容作为核心部分:

  • UIBezierPath
  • UITouch活动
  • CAShapeLayer
  • CoreGraphics中

答案 3 :(得分:2)

使用此广告单元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;
}

答案 4 :(得分:1)

如果您在代码中绘制所有内容,只需使用 - 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);

答案 5 :(得分:1)

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

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

默认情况下,使用opaque == YES创建图像上下文,因此您必须将其更改为NO。

答案 6 :(得分:0)

这适合我...

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

答案 7 :(得分:0)

// This Work 100%

- (void)touchesBegan:(NSSet *)触及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(), 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;

}