HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

UIGraphicsImageContext Memory Spike - Reducing Footprint

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
spikereducinguigraphicsimagecontextmemoryfootprint

Problem

I have a UIImage Category for iOS Objective-C which tints an image based on a given UIColor value. You can take a look at the method below:

- (UIImage *)tintImageWithTint:(UIColor *)color withIntensity:(float)alpha {
    CGSize size = self.size;

    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); // MEMORY SPIKE
    CGContextRef context = UIGraphicsGetCurrentContext();

    [self drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:1.0]; // MEMORY SPIKE

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextSetBlendMode(context, kCGBlendModeOverlay);
    CGContextSetAlpha(context, alpha);

    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(CGPointZero.x, CGPointZero.y, self.size.width, self.size.height));

    // Get the resized image from the context and a UIImage
    CGImageRef newImageRef = CGBitmapContextCreateImage(context); // MEMORY SPIKE
    UIImage *tintedImage = [UIImage imageWithCGImage:newImageRef];

    CGImageRelease(newImageRef);
    UIGraphicsEndImageContext();

    return tintedImage;
}


I've been testing this method with Xcode's Instruments app and found that it takes up more than 96.0 % of all bytes used during the life cycle of the app. That's crazy! It allocates more than 5 MB very quickly, which causes a level one memory warning and begins to terminate other running processes.

The image that I'm tinting is only a 111 KB, so I can't see how this code could possibly allocate more than 5 MB so quickly.

How can I improve the performance of this code and reduce its memory impact? I'm not very familiar with CoreGraphics, so any help would be appreciated.

Solution

your image might have 111 KB compressed as an jpg or a png. But for image processing it needs to be decompressed. It will be loaded into memory with 8 or 16 bit for each color channel. With RGB it would be up to 48 bit per pixel and 8 bit for the alpha cannel in case of png. So 5MB would represent roughly 1.25 million pixel, or something like 1000*1250 pixel.

Context

StackExchange Code Review Q#37423, answer score: 2

Revisions (0)

No revisions yet.