0

I am using the following code for applying image filters. In my app I am filtering for brightness, contrast and saturation. I am using three separate sliders each to change the values. As I continue to move the values, the memory consumption goes over 1.5 gb and crashes. Is there a way to reduce this memory consumption for a crash free implementation?

(void)setBrightnessAndContrastOf:(UIImage *)image { // forTarget:(UIImageView *)imgView {

    if (!image) {
        return;
    }

    CIImage *inputImage = [[CIImage alloc] initWithImage:image];
    CIFilter *exposureAdjustmentFilter = [CIFilter filterWithName:@"CIColorControls"];
    [exposureAdjustmentFilter setDefaults];
    [exposureAdjustmentFilter setValue:inputImage forKey:@"inputImage"];

    [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:self.contrastValue] forKey:@"inputContrast"]; //default = 1.00
    [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:self.brightnessValue] forKey:@"inputBrightness"]; //default = 0.00
    [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:self.saturationValue] forKey:@"inputSaturation"]; //default = 1.00
    CIImage *outputImage = [exposureAdjustmentFilter valueForKey:@"outputImage"];

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef tempImage = [context createCGImage:outputImage fromRect:[outputImage extent]];

    UIImage *newImage = [UIImage imageWithCGImage:tempImage];

    [imageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:NO];
    CGImageRelease(tempImage);

    inputImage = nil;
    context = nil;
    outputImage = nil;
    exposureAdjustmentFilter = nil;
}
Leigh
  • 28,765
  • 10
  • 55
  • 103
Nassif
  • 1,113
  • 2
  • 14
  • 34

2 Answers2

0

You're not supposed to do heavy image manipulation inside the main thread. Unless you've already implemented multithreading (which is not mentioned in your code snippet), please do so.

You might try:

dispatch_queue_t backgroundQueue = dispatch_queue_create("com.yourorg", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(backgroundQueue, ^
                   {
     // setBrightnessAndContrastOf method goes here

        dispatch_sync(mainQueue, ^ {

               //notify main thread about process status
                      });

          });

Since you're using ARC, crashes due to over consumption of memory is not very likely. However, if you block the main thread for too long, watchdog timer takes it out through the backdoor and shoots it right in the head.

Use instruments to monitor your heap size and try to find out the root cause.

metsburg
  • 2,021
  • 1
  • 20
  • 32
0

I am not sure what your setImage method is doing but I would move CGImageRelease(tempImage) before the performSelector.

Khaled Barazi
  • 8,681
  • 6
  • 42
  • 62