views:

489

answers:

2

Has anyone else come across this problem? I am resizing images pretty often with an NSTimer. After using Instruments it does not show any memory leaks but my objectalloc just continues to climb. It points directly to CGBitmapContextCreateImage.

Anyone know of a solution? or Even possible ideas?

-(UIImage *) resizedImage:(UIImage *)inImage : (CGRect)thumbRect : (double)interpolationQuality
{
    CGImageRef   imageRef = [inImage CGImage];
    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);

    if (alphaInfo == kCGImageAlphaNone)
     alphaInfo = kCGImageAlphaNoneSkipLast;

    // Build a bitmap context that's the size of the thumbRect
    CGContextRef bitmap = CGBitmapContextCreate(
        NULL,
        thumbRect.size.width,
        thumbRect.size.height,  
        CGImageGetBitsPerComponent(imageRef),
        4 * thumbRect.size.width, 
        CGImageGetColorSpace(imageRef),
        alphaInfo
        );

    // Draw into the context, this scales the image
    CGContextSetInterpolationQuality(bitmap, interpolationQuality);
    CGContextDrawImage(bitmap, thumbRect, imageRef);

    // Get an image from the context and a UIImage
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap); // ok if NULL
    CGImageRelease(ref);

    return [result autorelease];
}
A: 

Just a sanity check: are you releasing the return UIImage -- normally i would expect a function that allocating a new object (in this case a UIImage) to have create in the name?

Perhaps you want

return [result autorelease]

?

olliej
I actualy just added that line to my code a couple minutes ago, That didn't make a difference either. The CGBitmapContextCreate is murdering my objectalloc
bbullis21
A: 

Why not use the simpler UIGraphicsBeginImageContext?

@implementation UIImage(ResizeExtension)
- (UIImage *)resizedImageWithSize:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)interpolationQuality;
@end
@implementation UIImage(ResizeExtension)
- (UIImage *)resizedImageWithSize:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)interpolationQuality
{
 UIGraphicsBeginImageContext(newSize);
 CGContextRef context = UIGraphicsGetCurrentContext();
 CGContextSetInterpolationQuality(context, interpolationQuality);
 [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
 UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();
 return result;
}

@end

Also, this will return an image retained by the current autorelease pool; if you are creating many of these images in a loop, allocate and drain an NSAutoreleasePool manually.

rpetrich
UIGraphicsBeginImageContext isn't thread safe
Toon Van Acker
UIImage isn't technically thread-safe either (although it usually works)
rpetrich
Thanks for the tips, but drawInRect doesn't provide the same InterpolationQuality affect. This is what I was basically doing, calling my above resizeImage script to shrink an image to a small resolution with a high InterpolationQuality, and then resizing it back to normal. The end result is a Photoshop like Gaussian blurred image. I have been searching for days to understand why CGBitmapContextCreate builds up the objectalloc. Thank you for your tips, I'm gonna keep working with your snippet to see if I can get the same end result. You know of any other possible way?
bbullis21
I wasn't aware CGContextSetInterpolationQuality doesn't affect drawInRect. You can swap out the drawInRect call with CGContextDrawImage, but you may have to call CGContextScaleCTM to get the coordinate system to match up.
rpetrich
Thanks for the ideas of using CGContextDrawImage, I gave it a shot and still the affect is different for some reason. Not sure why exactly. This is ObjectAlloc build up is really killing my production time on this project.
bbullis21