美文网首页ios开发整理
iOS 图片处理之任意路径剪切

iOS 图片处理之任意路径剪切

作者: 一只代码狗 | 来源:发表于2018-02-26 17:32 被阅读26次

    思路分析:
    第一想法:
    首先CGContextMoveToPoint起始点
    然后使用CGContextAddLineToPoint使用给添加点
    画完以后CGContextAddLineToPoint起始点闭合路径
    使用CGContextClip方法剪切上下文
    将图片绘制到上下文
    我们使用该想法去实现过程中发现以下问题
    UIGraphicsBeginImageContextWithOptions方法开启一个上下文
    参数是CGSize,所以直接绘图的得到的位置是错误的
    解决方案:
    我们首先获取路径所在的矩形区域
    使用 CGContextDrawImage(context, myRect, imageRef),将该区域的图片绘制到区域中!
    获取到矩形区域的图片
    然后重新开启一个获取到的矩形区域的上下文
    添加闭合路径
    剪切上下文,绘制得到正确的图片
    注意事项:使用UIGraphicsBeginImageContextWithOptions开启上下文的时候指定scale参数为self.image.scale否则会有问题

    /*
     *  penPaths NSMutableArray 存储 CGPoint生成的NSValue
     *  rect CGPoints的范围
     */
    - (UIImage *)clipAnyShapeImageAtPath:(NSMutableArray *)penPaths
                                  atRect:(CGRect)rect {
        // 防止线画出UIImageView范围之外
        CGFloat width= self.frame.size.width;
        CGFloat rationScale = (width / self.image.size.width);
        CGFloat origX = (rect.origin.x - self.frame.origin.x) / rationScale;
        CGFloat origY = (rect.origin.y - self.frame.origin.y) / rationScale;
        CGFloat oriWidth = rect.size.width / rationScale;
        CGFloat oriHeight = rect.size.height / rationScale;
        
        if (origX < 0) {
            oriWidth = oriWidth + origX;
            origX = 0;
        }
        
        if (origY < 0) {
            oriHeight = oriHeight + origY;
            origY = 0;
        }
        
        // 绘制图片到点的矩形范围内
        CGRect myRect = CGRectMake(origX, origY, oriWidth, oriHeight);
        CGImageRef  imageRef = CGImageCreateWithImageInRect(self.image.CGImage, myRect);
        
        UIGraphicsBeginImageContextWithOptions(myRect.size, NO, self.image.scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        CGContextDrawImage(context, myRect, imageRef);
        UIImage * newImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
        UIGraphicsEndImageContext();
        
        // 任意形状截取图片
        // clip any path
        for (int i = 0; i < penPaths.count; i++) {
            NSValue *valueI = penPaths[i];
            CGPoint pointI = [valueI CGPointValue];
            pointI.x -= myRect.origin.x;
            pointI.y -= myRect.origin.y;
            
            if (pointI.x < 0) {
                pointI.x = 0;
            }
            
            if (pointI.y < 0) {
                pointI.x = 0;
            }
            
            penPaths[i] = [NSValue valueWithCGPoint:pointI];
        }
        
        UIGraphicsBeginImageContextWithOptions(rect.size, NO, self.image.scale);
        context = UIGraphicsGetCurrentContext();
        NSValue *value0 = penPaths[0];
        CGPoint point0 = [value0 CGPointValue];
        CGContextMoveToPoint(context, point0.x, point0.y);
        
        for (int i = 1; i < penPaths.count; i++) {
            NSValue *valueI = penPaths[i];
            CGPoint pointI = [valueI CGPointValue];
            CGContextAddLineToPoint(context, pointI.x, pointI.y);
        }
        CGContextAddLineToPoint(context, point0.x, point0.y);
        CGContextClip(context);
        [newImage drawInRect:CGRectMake(0, 0, rect.size.width, rect.size.height)];
        CGContextDrawPath(context, kCGPathFill);
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return image;
    }
    
    跪求Star

    相关文章

      网友评论

        本文标题:iOS 图片处理之任意路径剪切

        本文链接:https://www.haomeiwen.com/subject/eqvyxftx.html