4

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

在此处输入图像描述

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

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

但结果是

在此处输入图像描述

谁能指出我正确的方向,我需要做什么?

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

}

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

4

1 回答 1

1

这是一个很好的库来满足您的要求,如下所示:

对于 Swift 试试这个:ZImageCropper

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

UIBezierPath、UITouch 事件、CAShapeLayer、CoreGraphics

请检查并回复我。

于 2018-05-26T03:46:19.163 回答