我尝试在一次超过100个UIimage中进行图像裁剪和羽化。但是在iPhone6中运行它时总会出现内存问题。Memory Leak checking by Instrucment
这是代码。我如何优化我的代码以最好地使用内存。
-(UIImage*)stitchingImagesNon360:(NSMutableDictionary*) images
{
UIImage *processImage = [images objectForKey:@"0"];
processImage= [self rotateImageAppropriately: processImage];
cropimageWidth=processImage.size.width/factor;
CGSize size = CGSizeMake(processImage.size.width/factor*(int)images.count, processImage.size.height);
UIGraphicsBeginImageContext(size);
@autoreleasepool
{
for (int j=0; j<(int)images.count-1; j=j+1)
{
NSString* tempIndex=[NSString stringWithFormat:@"%d",j];
processImage = [images objectForKey:tempIndex];
processImage= [self rotateImageAppropriately: processImage];
if (j!=images.count)
{
CGRect cropArea= CGRectMake(processImage.size.width*0.5, 0, cropimageWidth*2, processImage.size.height);
processImage=[self cropImage:processImage cropArea:cropArea];
}
if (j!=0)
{
processImage=[self featheredImageWithImage:processImage endPoint:cropimageWidth/3];
}
CGPoint image1Point = CGPointMake(cropimageWidth*(j), 0);
[processImage drawAtPoint:image1Point];
// [cropImage drawAtPoint:image1Point blendMode:kCGBlendModeNormal alpha:1];
}
}
UIImage* stitchedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
images=nil;
return stitchedImage;
}
CGContextRef ctx;
- (UIImage *) featheredImageWithImage:(UIImage *) image endPoint: (float) endPointX
{
@autoreleasepool {
// Locations of where the feather starts and ends (0 -> 1)
const CGFloat featherLocations[] = {1, 0};
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
ctx = UIGraphicsGetCurrentContext();
// Draw the original image
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
// A 'knock-out' gradient is used to generate a feather effect,
// the alpha channel on the colors defines the alpha of the drawn image
NSArray *gradientColors = @[(id)[UIColor colorWithWhite:0 alpha:1].CGColor,
(id)[UIColor colorWithWhite:0 alpha:0].CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(CGImageGetColorSpace(image.CGImage), (__bridge CFArrayRef)gradientColors, featherLocations);
// Because we're changing the draw mode below,
// take a snapshot of the current draw settings so we can reset them after
CGContextSaveGState(ctx);
// The kCGBlendModeDestinationIn blend mode will provide a'knock-out' effect on
// the previously drawn content, using the alpha channels of the gradient's colors
CGContextSetBlendMode(ctx, kCGBlendModeDestinationIn);
CGPoint startPoint = CGPointMake(0, 0);
CGPoint endPoint = CGPointMake(endPointX, 0);
CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
gradient = NULL;
CGContextRestoreGState(ctx);
// Get the UIImage version
UIImage *featheredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
ctx=nil;
return featheredImage;
}
}
- (UIImage *)rotateImageAppropriately:(UIImage *)image
{
@autoreleasepool {
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
CGFloat boundHeight;
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(bounds.size.width, 0);
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//CGImageRelease(imgRef);
//CGContextRelease(context);
return imageCopy;
}
}
答案 0 :(得分:1)
临时内存在选择运行循环之前不会释放。解决这个问题的方法是在内部循环中添加一个自动释放池。这样就可以为循环的每次迭代释放临时内存。
for (int j=0; j<(int)images.count-1; j=j+1)
{
autoreleasepool {
/* code */
}
}
你的代码只有在>>循环之外的自动释放池,并且只有在循环的所有迭代之后才会释放临时代码。