I need advice on how to use CIFilter efficiently on memory. Basically, I'm chaining two filters together. The tricky part is I have to convert UIImage to CIImage first before calling the filters. The code is posted below:

CIImage *foreground = [CIImage imageWithCGImage:first.CGImage options:nil];
CIImage *background = [CIImage imageWithCGImage:second.CGImage options:nil];

CIFilter *softLightBlendFilter = [CIFilter filterWithName:@"CISoftLightBlendMode"];
[softLightBlendFilter setDefaults];
[softLightBlendFilter setValue:foreground forKey:kCIInputImageKey];
[softLightBlendFilter setValue:background forKey:kCIInputBackgroundImageKey];

CIImage *result = [softLightBlendFilter outputImage];

foreground = nil;
background = nil;
softLightBlendFilter = nil;

CIFilter *gammaAdjustFilter = [CIFilter filterWithName:@"CIGammaAdjust"];
[gammaAdjustFilter setDefaults];
[gammaAdjustFilter setValue:result forKey:kCIInputImageKey];
[gammaAdjustFilter setValue:[NSNumber numberWithFloat:value] forKey:@"inputPower"];
result = [gammaAdjustFilter valueForKey:kCIOutputImageKey];

gammaAdjustFilter = nil;

CIContext *context = [CIContext contextWithOptions:nil];
CGRect extent = [result extent];
CGImageRef cgImage = [context createCGImage:result fromRect:extent];

UIImage *image = [UIImage imageWithCGImage:cgImage scale:1.0 orientation:first.imageOrientation];

CFRelease(cgImage);
result = nil;

return image;

And this code easily shoots memory up to 200MB, which will cause the app to crash.

So what am I doing wrong? How can I fix this?

有帮助吗?

解决方案

Calling image.CGImage is loading the image into memory.

You can try to use

CIImage *ciImage = [CIImage imageWithContentsOfURL:imageUrl options:@{kCIImageColorSpace:[NSNull null]}];

CIImage *ciImage = [CIImage imageWithCGImage:first.CGImage options:nil];

instead of

CIImage *ciImage = [CIImage imageWithCGImage:uiImage.CGImage options:nil];

Another options is to tile the image, apply the filters on the tiles and then stitch them together again..

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top