Search code examples
iosuiimagecifilter

Cannot CIFilter image twice CGImage nil the seconds time


I'm applying a filter to a filtered image in a custom UIImageView class so that when I set "hue" it filters the image. However, when I call the following code, [[self image] CGImage] the first time around returns the proper value. The second time around the [[self image] CGImage] is nil so the CIFilter return is also nil.

Is there a better way to do this?

- (void)setHue:(CGFloat)aHue
{
    hue = aHue;
    NSLog( @"CG Image? %@", [[self image] CGImage] );
    CIFilter *filter = [CIFilter filterWithName:@"CIHueAdjust"];
    [filter setDefaults];
    [filter setValue:[CIImage imageWithCGImage:[[self image] CGImage]]
              forKey:@"inputImage"];
    NSLog( @"Setting new hue %f", aHue );
    [filter setValue:[NSNumber numberWithFloat:aHue] forKey:@"inputAngle"];
    [self setImage:[UIImage imageWithCIImage:[filter valueForKey:@"outputImage"]]];

    NSLog( @"Output image %@", [self image] );
}

Solution

  • An UIImage can be backed by either a CGImage or CIImage. After you run this function once and [UIImage imageWithCIImage] is called, the new UIImage is now backed by a CIImage.

    This is actually good because the next time this function can be run even faster! You can simply check to see if CIImage exists and use it directly:

    - (void)setHue:(CGFloat)aHue
    {
        hue = aHue;
        NSLog( @"CG Image? %@", [[self image] CGImage] );
        CIFilter *filter = [CIFilter filterWithName:@"CIHueAdjust"];
        [filter setDefaults];
        if ([[self image] CGImage]) {
          [filter setValue:[CIImage imageWithCGImage:[[self image] CGImage]] forKey:@"inputImage"];
        }
        else {
          [filter setValue:[[self image] CIImage] forKey:@"inputImage"];
        }
    
        NSLog( @"Setting new hue %f", aHue );
        [filter setValue:[NSNumber numberWithFloat:aHue] forKey:@"inputAngle"];
        [self setImage:[UIImage imageWithCIImage:[filter valueForKey:@"outputImage"]]];
    
        NSLog( @"Output image %@", [self image] );
    }