使用贝塞尔曲线路径自定义图像裁剪

时间:2013-04-03 12:09:01

标签: iphone ios image crop

嗨我正在尝试制作一个自定义裁剪工具,使用户可以使用贝塞尔曲线路径创建自定义封闭区域。

enter image description here

我用来剪辑带路径的imageView的代码是

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.path = clippingPath.CGPath;
[imgView.layer setMask:maskLayer];

但结果是

enter image description here

任何人都可以指出我正确的方向,我需要做什么?

-(void)longPressAddPoint:(UITapGestureRecognizer*)gesture
{   ctr++;
    CGPoint  touchpoint=[gesture locationInView:self];
    [ptsNew addObject:[NSValue valueWithCGPoint:[gesture locationInView:self] ]];
    if(ctr>1)
    {
      if(CGRectContainsPoint([self viewWithTag:1].frame, [gesture locationInView:self]))
      {
          pathClosed=YES;
          touchpoint=[self viewWithTag:1].center;

      }

    UIView *greenCircle=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
    greenCircle.center=touchpoint;
    greenCircle.backgroundColor=[UIColor greenColor];
        [greenCircle setTag:ctr];
    [greenCircle.layer setCornerRadius:10];
    [self addSubview:greenCircle];
        [pathMain appendPath:[pathCurrent bezierPathByReversingPath]];
        pathMain.usesEvenOddFillRule=YES;
        [pathCurrent moveToPoint:[[ptsNew objectAtIndex:ptsNew.count-2] CGPointValue]];
        [pathCurrent addCurveToPoint:[[ptsNew objectAtIndex:ptsNew.count-1] CGPointValue] controlPoint1:firstControllPoint.center controlPoint2:[[ptsNew objectAtIndex:ptsNew.count-1] CGPointValue]]; // this is how a Bezier curve is appended to a path
        [self setNeedsDisplay];


    }
    else {

        UIView *greenCircle=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
        greenCircle.center=touchpoint;
        greenCircle.backgroundColor=[UIColor greenColor];
        [greenCircle setTag:ctr];
        [greenCircle.layer setCornerRadius:10];
        [self addSubview:greenCircle];
    }
}
- (void)drawRect:(CGRect)rect
{   
    [pathCurrent stroke];
    [pathMain stroke];

}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];
    if(CGRectContainsPoint(firstControllPoint.frame,[touch locationInView:self] )&&(ptsNew.count>=2))
    {
       flagForTouch=YES;
    }
    else {
        flagForTouch=NO;
    }

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
       if (flagForTouch) // 4th point
    {
        [pathCurrent removeAllPoints];
        [self setNeedsDisplay];
        [pathCurrent moveToPoint:[[ptsNew objectAtIndex:ptsNew.count-2] CGPointValue]];
        [pathCurrent addCurveToPoint:[[ptsNew objectAtIndex:ptsNew.count-1] CGPointValue] controlPoint1:firstControllPoint.center controlPoint2:[[ptsNew objectAtIndex:ptsNew.count-1] CGPointValue]]; // this is how a Bezier curve is appended to a path
        [self setNeedsDisplay];

    }
    if(flagForTouch)
    firstControllPoint.center=[[touches anyObject] locationInView:self];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{

}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

#pragma mark:- clipping image based on path
- (void) setClippingPath:(UIBezierPath *)clippingPath imageViewObj: (UIImageView *)imgView;
{
//    if (![[imgView layer] mask])
//        [[imgView layer] setMask:[CAShapeLayer layer]];
//    
//    [(CAShapeLayer*) [[imgView layer] mask] setPath:[clippingPath CGPath]];


    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.bounds;
    clippingPath.usesEvenOddFillRule=YES;
    maskLayer.path = clippingPath.CGPath;
    [imgView.layer setMask:maskLayer];
    UIGraphicsBeginImageContext(self.frame.size);
}

-(void)getCroppedImage:(sendImageBlock)Image
{
    sendImageToBase=Image;
}
-(void)cropIt
{
    if (pathClosed) {
        NSLog(@"path closed crop now");
        [pathMain appendPath:[pathCurrent bezierPathByReversingPath]];
        pathMain.usesEvenOddFillRule=YES;
        [self setClippingPath:[pathMain bezierPathByReversingPath] imageViewObj:self.imageToBeCropped];
        sendImageToBase(self.imageToBeCropped);
    }

}

我有一个Path main(作为剪切路径传递)我创建当前路径,用户可以添加曲线。当用户添加新路径时,当前路径将附加到主路径。

1 个答案:

答案 0 :(得分:0)

这是一个符合您要求的好图书馆,如下所示:

对于Swift试试这个: ZImageCropper

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

UIBezierPath, UITouch活动, CAShapeLayer, CoreGraphics中

请检查并将我还原。