思路分析:
第一想法:
首先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;
}