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:
Apply the sepia filter to tint an image with a reddish-brown hue.
Add the bloom filter to accentuate highlights.
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.