如何将 UIImage 切成碎片(如披萨)并将每个碎片保存在数组中?
How to cut UIImage to pieces(like pizza) and to save each one in array?
数组保存没问题,就是不知道怎么切。我找到了如何将它切成矩形,但我找不到如何像披萨一样切割它。
@implementation UIImage (Crop)
- (UIImage *)crop:(CGRect)rect {
rect = CGRectMake(rect.origin.x*self.scale,
rect.origin.y*self.scale,
rect.size.width*self.scale,
rect.size.height*self.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage *result = [UIImage imageWithCGImage:imageRef
scale:self.scale
orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
}
@end
在图片上我试图展示我想做的事情。
所以核心是你想从你的图像中剪切ARC。这里就不评论代码了,因为我在代码里面写了一些注释。
- (NSArray *)pizzaSlicesFromImage:(UIImage *)image withNumberOfSlices:(NSUInteger)numberOfSlices {
if (!image) {
NSLog(@"You need to pass an image to slice it! nil image argument occured."); // use cocoa lumberjack instead of logs
return nil;
} else if (numberOfSlices == 0) { // 0 slices? then you don't want the image at all
return nil;
} else if (numberOfSlices == 1) { // 1 slice? then it's whole image, just wrapped in array
return @[image];
}
CGFloat fullCircle = 2 * M_PI;
CGFloat singleSliceAngle = fullCircle / numberOfSlices;
CGFloat previousSliceStartAngle = 0;
NSMutableArray *mSlicesOfImage = [NSMutableArray new];
for (NSUInteger i = 0; i < numberOfSlices; i++) {
UIImage *sliceImage = [self imageFromAngle:previousSliceStartAngle toAngle:(previousSliceStartAngle + singleSliceAngle) fromImage:image];
if (sliceImage) {
[mSlicesOfImage addObject:sliceImage];
}
previousSliceStartAngle += singleSliceAngle;
}
// return non-mutable array
return mSlicesOfImage.copy;
}
- (UIImage *)imageFromAngle:(CGFloat)fromAngle toAngle:(CGFloat)toAngle fromImage:(UIImage *)image {
// firstly let's get proper size for the canvas
CGRect imageRect = CGRectMake(0.f, 0.f, image.size.width, image.size.height);
CGPoint centerPoint = CGPointMake(CGRectGetMidX(imageRect), CGRectGetMidY(imageRect));
// start the drawing
UIGraphicsBeginImageContext(imageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// we need to perform this to fix upside-down rotation
CGContextTranslateCTM(context, 0, imageRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// now slice an arc from the circle
CGContextBeginPath(context);
CGContextMoveToPoint(context, centerPoint.x, centerPoint.y); // move to the center of drawing
CGContextAddArc(context, centerPoint.x, centerPoint.y, MAX(CGRectGetWidth(imageRect), CGRectGetHeight(imageRect)) / 2.f, fromAngle, toAngle, 0); // draw the arc
// ! if you want NOT to cut outer area to form the circle, just increase 4th value (radius) to cover "corners" of the rect drawn on the circle. I did it this way, because it looks like a pizza, like you wanted.
CGContextClosePath(context);
CGContextClip(context);
// get the image, purge memory
CGContextDrawImage(context, imageRect, image.CGImage);
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// this is one slice
return resultImage;
}
这不是一个完整的解决方案,因为我没有更多时间来完成它,但我会尝试稍后完成它。剩下的就是把图剪小一点,但我没有时间完成,所以只回答了一部分。
希望对您有所帮助 :) 希望稍后编辑此答案以添加缺少的剪辑部分。
顺便说一句:我已经基于上述实现创建了一个模块。欢迎您查看:https://github.com/natalia-osa/NORosettaView.
数组保存没问题,就是不知道怎么切。我找到了如何将它切成矩形,但我找不到如何像披萨一样切割它。
@implementation UIImage (Crop)
- (UIImage *)crop:(CGRect)rect {
rect = CGRectMake(rect.origin.x*self.scale,
rect.origin.y*self.scale,
rect.size.width*self.scale,
rect.size.height*self.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage *result = [UIImage imageWithCGImage:imageRef
scale:self.scale
orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
}
@end
在图片上我试图展示我想做的事情。
所以核心是你想从你的图像中剪切ARC。这里就不评论代码了,因为我在代码里面写了一些注释。
- (NSArray *)pizzaSlicesFromImage:(UIImage *)image withNumberOfSlices:(NSUInteger)numberOfSlices {
if (!image) {
NSLog(@"You need to pass an image to slice it! nil image argument occured."); // use cocoa lumberjack instead of logs
return nil;
} else if (numberOfSlices == 0) { // 0 slices? then you don't want the image at all
return nil;
} else if (numberOfSlices == 1) { // 1 slice? then it's whole image, just wrapped in array
return @[image];
}
CGFloat fullCircle = 2 * M_PI;
CGFloat singleSliceAngle = fullCircle / numberOfSlices;
CGFloat previousSliceStartAngle = 0;
NSMutableArray *mSlicesOfImage = [NSMutableArray new];
for (NSUInteger i = 0; i < numberOfSlices; i++) {
UIImage *sliceImage = [self imageFromAngle:previousSliceStartAngle toAngle:(previousSliceStartAngle + singleSliceAngle) fromImage:image];
if (sliceImage) {
[mSlicesOfImage addObject:sliceImage];
}
previousSliceStartAngle += singleSliceAngle;
}
// return non-mutable array
return mSlicesOfImage.copy;
}
- (UIImage *)imageFromAngle:(CGFloat)fromAngle toAngle:(CGFloat)toAngle fromImage:(UIImage *)image {
// firstly let's get proper size for the canvas
CGRect imageRect = CGRectMake(0.f, 0.f, image.size.width, image.size.height);
CGPoint centerPoint = CGPointMake(CGRectGetMidX(imageRect), CGRectGetMidY(imageRect));
// start the drawing
UIGraphicsBeginImageContext(imageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// we need to perform this to fix upside-down rotation
CGContextTranslateCTM(context, 0, imageRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// now slice an arc from the circle
CGContextBeginPath(context);
CGContextMoveToPoint(context, centerPoint.x, centerPoint.y); // move to the center of drawing
CGContextAddArc(context, centerPoint.x, centerPoint.y, MAX(CGRectGetWidth(imageRect), CGRectGetHeight(imageRect)) / 2.f, fromAngle, toAngle, 0); // draw the arc
// ! if you want NOT to cut outer area to form the circle, just increase 4th value (radius) to cover "corners" of the rect drawn on the circle. I did it this way, because it looks like a pizza, like you wanted.
CGContextClosePath(context);
CGContextClip(context);
// get the image, purge memory
CGContextDrawImage(context, imageRect, image.CGImage);
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// this is one slice
return resultImage;
}
这不是一个完整的解决方案,因为我没有更多时间来完成它,但我会尝试稍后完成它。剩下的就是把图剪小一点,但我没有时间完成,所以只回答了一部分。
希望对您有所帮助 :) 希望稍后编辑此答案以添加缺少的剪辑部分。
顺便说一句:我已经基于上述实现创建了一个模块。欢迎您查看:https://github.com/natalia-osa/NORosettaView.