Contents

Processing an Image Using Built-in Filters

Apply effects such as sepia tint, highlight strengthening, and scaling to images.

Overview

You can add effects to images by applying Core Image filters to CIImage objects. Figure 1 shows three filters chained together to achieve a cumulative effect:

  1. Apply the sepia filter to tint an image with a reddish-brown hue.

  2. Add the bloom filter to accentuate highlights.

  3. Use the Lanczos scale filter to scale an image down.

[Image]

Create a Context

CIImage processing occurs in a CIContext object. Creating a CIContext is expensive, so create one during your initial setup and reuse it throughout your app.

CIContext* context = [CIContext context];

Load an Image to Process

The next step is to load an image to process. This example loads an image from the project bundle.

NSURL* imageURL = [[NSBundle mainBundle] URLForResource:@"YourImageName" withExtension:@"png"];
CIImage* originalCIImage = [CIImage imageWithContentsOfURL:imageURL];
self.imageView.image = [UIImage imageWithCIImage:originalCIImage];

The CIImage object isn’t itself a displayable image, but rather image data. To display it, you must convert it to another type, such as UIImage.

Apply Built-In Core Image Filters

A CIFilter represents a single operation or recipe for a particular effect. To process a CIImage object, pass it through CIFilter objects. You can subclass CIFilter or draw from the existing library of built-in filters.

Tint Reddish-Brown with the Sepia Filter

Although you can chain filters without separating them into functions, the following example shows how to configure a single CIFilter, the sepiaTone() filter.

- (CIImage*) sepiaFilterImage: (CIImage*)inputImage withIntensity:(CGFloat)intensity {
    CIFilter<CISepiaTone>* sepiaFilter = CIFilter.sepiaToneFilter;
    sepiaFilter.inputImage = inputImage;
    sepiaFilter.intensity = intensity;
    return sepiaFilter.outputImage;
}

To pass the image through the filter, call the sepia filter function.

CIImage* sepiaCIImage = [self sepiaFilterImage:originalCIImage withIntensity:0.9];

You can check the intermediate result at any point in the filter chain by converting from CIImage to a UIImage. You can then assign this UIImage to a UIImageView for display.

_imageView.image = [UIImage imageWithCIImage:sepiaCIImage];

Strengthen Highlights with the Bloom Filter

The bloom filter accentuates the highlights of an image. You can apply it as part of a chain without factoring it into a separate function, but this example encapsulates its functionality into a function.

- (CIImage*) bloomFilterImage: (CIImage*)inputImage withIntensity:(CGFloat)intensity radius:(CGFloat)radius {
    CIFilter<CIBloom>* bloomFilter = CIFilter.bloomFilter;
    bloomFilter.inputImage = inputImage;
    bloomFilter.intensity = intensity;
    bloomFilter.radius = radius;
    return bloomFilter.outputImage;
}

Like the sepia filter, the intensity of the bloom filter’s effect ranges between 0 and 1, with 1 being the most intense effect. The bloom filter has an additional radius parameter to determine how much the glowing regions expand. Experiment with a range to values to fine tune the effect, or assign the input parameter to a control like a UISlider to allow your users to tweak its values.

To display the output, convert the CIImage to a UIImage.

CIImage* bloomCIImage = [self bloomFilterImage:sepiaCIImage withIntensity:1 radius:10];
_filteredImageView.image = [UIImage imageWithCIImage:bloomCIImage];

Scale Image Size with the Lanczos Scale Filter

Apply the lanczosScaleTransform() to obtain a high-quality downsampling of the image, preserving the original image’s aspect ratio through the lanczosScaleTransform() filter’s parameter aspectRatio. For built-in Core Image filters, calculate the aspect ratio as the image’s width over height.

CGFloat imageWidth = originalUIImage.size.width;
CGFloat imageHeight = originalUIImage.size.height;
CGFloat aspectRatio = imageHeight / imageWidth;
CIImage* scaledCIImage = [self scaleFilterImage:bloomCIImage withAspectRatio:aspectRatio scale:0.05];

Like other built-in filters, the lanczosScaleTransform() filter also outputs its result as a CIImage.

- (CIImage*) scaleFilterImage: (CIImage*)inputImage withAspectRatio:(CGFloat)aspectRatio scale:(CGFloat)scale {
    CIFilter<CILanczosScaleTransform>* scaleFilter = CIFilter.lanczosScaleTransformFilter;
    scaleFilter.inputImage = inputImage;
    scaleFilter.scale = scale;
    scaleFilter.aspectRatio = aspectRatio;
    return scaleFilter.outputImage;
}
_imageView.image = [UIImage imageWithCIImage:scaledCIImage];

In addition to trying out the built-in filters for a fixed effect, you can combine filters in certain Filter Recipes to accomplish tasks such as Applying a Chroma Key Effect, Selectively Focusing on an Image, Customizing Image Transitions, and Simulating Scratchy Analog Film.

See Also

Essentials