ios开发整理

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

2018-02-26  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读