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