Memory Leak in image rotation

Discussion in 'iOS Programming' started by xArtx, Mar 18, 2013.

  1. xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #1
    Hi Guys,
    I have this working fine to rotate an image at arbitrary angles,
    except when it is called enough times, I get low memory warnings,
    followed by App crash.
    THe function originally had a release or autorelease statement in it
    that had to be removed for an ARC project.

    Code:
    
    - (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
    {
        
        CGFloat angleInRadians = angle * (M_PI / 180);
        CGFloat width = CGImageGetWidth(imgRef);
        CGFloat height = CGImageGetHeight(imgRef);
        
        CGRect imgRect = CGRectMake(0, 0, width, height);
        CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
        CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
        
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        
        CGContextRef bmContext = CGBitmapContextCreate(NULL,
                                                       rotatedRect.size.width,
                                                       rotatedRect.size.height,
                                                       8,
                                                       0,
                                                       colorSpace,
                                                       kCGImageAlphaPremultipliedFirst);
        CGContextSetAllowsAntialiasing(bmContext, YES);
        CGContextSetShouldAntialias(bmContext, YES);
        CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
        CGColorSpaceRelease(colorSpace);
        CGContextTranslateCTM(bmContext,
                              +(rotatedRect.size.width/2),
                              +(rotatedRect.size.height/2));
        CGContextRotateCTM(bmContext, angleInRadians);
        CGContextTranslateCTM(bmContext,
                              -(rotatedRect.size.width/2),
                              -(rotatedRect.size.height/2));
        CGContextDrawImage(bmContext, CGRectMake(0, 0,
                                                 rotatedRect.size.width,
                                                 rotatedRect.size.height),
                           imgRef);
        
        rotatedImage = CGBitmapContextCreateImage(bmContext);
        CFRelease(bmContext);
          
        return rotatedImage;
    }
    
    Called with this:

    Code:
    CGImageRef imageRef = [self CGImageRotatedByAngle:[oldImage CGImage] angle:rotation];
    rotImage = [UIImage imageWithCGImage: imageRef];
    
    Any ideas as to why this is happening?
    As I said, it does work for a while to rotate an image a few times.
    I keep changing the angle of rotation, but am only writing the result back to
    rotImage, not creating a bunch of new image objects.
    Cheers, Art.
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    My knowledge of CoreGraphics is rather limited but the Discussion for CGBitmapContextCreateImage states:
    I think you may need to use CGImageRelease at some point but I'm not sure where. Perhaps have your method create and return a UIImage instead so that you can call imageWithCGImage: and then CGImageRelease before the method ends.
     
  3. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #3
    As Dejo says, you need to release the CFImage once you are done with it:


    Code:
    CGImageRef imageRef = [self CGImageRotatedByAngle:[oldImage CGImage] angle:rotation];
    rotImage = [UIImage imageWithCGImage: imageRef];
    CGImageRelease(imageRef);
    

    ARC does not manage Core Foundation objects for you. Your method CGImageRotatedByAngle should really be renamed to have the word create in it's name. I'd suggest CGCreateImageRoatedByAngle:

    Then it will be more apparent that the method follows the Core Foundation "Create Rule"
     
  4. xArtx, Mar 19, 2013
    Last edited: Mar 19, 2013

    xArtx thread starter macrumors 6502a

    Joined:
    Mar 30, 2012
    #4
    Thanks, I'll give it a shot :)

    Just a curiosity... How much memory does your App get?
    If you kept allocating memory, your App would crash,
    but iOS doesn't.
    I wonder if the initial allocation of RAM is expanded by iOS if you allocate more memory at runtime.
     

Share This Page