使用UIGraphicsBeginImageContext

时间:2016-02-04 02:02:06

标签: ios objective-c memory-leaks

我尝试在一次超过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;
    }
}

1 个答案:

答案 0 :(得分:1)

临时内存在选择运行循环之前不会释放。解决这个问题的方法是在内部循环中添加一个自动释放池。这样就可以为循环的每次迭代释放临时内存。

for (int j=0; j<(int)images.count-1; j=j+1)
{
    autoreleasepool {
      /* code */ 
    }
}

你的代码只有在>循环之外的自动释放池,并且只有在循环的所有迭代之后才会释放临时代码。