iOS Programming Recipe 21: Photo Filtering Using Core Image

This week I thought I would have a bit of fun and explore image manipulation using Core Image. This sounds like it could be pretty tough, but Apple has actually made this very easy. In this Recipe we’ll be creating a photo filter app that will let you choose a photo or take a photo using the camera and filter it.

Assumptions

  • You know the basics of Xcode, If not, we got you covered: Familiarizing Yourself With Xcode
  • You know how to create outlets and actions using the interace builder
  • You have a developer account and can run this app on hardware, This will be necessary if you want to capture an image using the camera

Setting Up the Project

Setting Up the Framework

Go ahead and start with a single view controller application using storyboards and title it “ImageFilterApp”.

For this App we’ll need to use the Core Image framework. To add a framework select the top level project from the project navigator on the left and scroll down in the main window to “Linked Frameworks and Libraries”. Here you can press the “+” button to add the new framework. When the dialogue opens choose the “CoreImage.framework” and press the “Add” button.

image1

now open up the viewController.h file and import the Core Image Framework by adding the following line to the top of the file:


1
#import <CoreImage/CoreImage.h>

Now go ahead and switch over to the storyboard so we can design our interface.

Setting Up the Interface

Drag three buttons on the screen and make them all 135 points wide by 43 tall.

Drag an imageView onto the screen and give it height of 284 points and a width of 213 points. This represents a 4:3 aspect ratio.

Add a label to the top of the screen.

Change all the text to match my view in the image below:

image2

Now we’ll want to create the outlets.

Creating the Outlets

Switch to the split view editor mode and control click and drag each item to the viewController.h file and give them the following associations.

  • outlet: imageView
  • action: pickImage
  • action: captureImage
  • action: filterImage

Your viewController.h file should now look like the following:


1
2
3
4
5
6
7
8
9
10
11
12
13
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>


@interface ViewController : UIViewController

@property (strong, nonatomic) IBOutlet UIImageView *imageView;

- (IBAction)pickImage:(id)sender;
- (IBAction)captureImage:(id)sender;
- (IBAction)filterImage:(id)sender;

@end

The last thing we’ll want to do is add a couple of delegate protocol declerations. Modify the the @interface line in the ViewController.h file to:

@interface ViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

These will allow us to implement the picker so we can either choose an image or capture one. More on that later.

Hashing Out the Code

In the body of this code there are a few things we’ll want to do. The first thing will be setting up the image picker, then we’ll implement the delegate which will populate the image view , lastly we’ll fill in the filterImage method.

Setting Up the Image Picker

Ok the first thing we’ll do is set up our pickImage and captureImage methods.
These two methods will look identical except for the source type will be changed from the camera to the photoLibrary.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- (IBAction)pickImage:(id)sender {

    UIImagePickerController *imagePicker;
    imagePicker = [[UIImagePickerController alloc] init];

    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    imagePicker.delegate = self;
    [self presentViewController:imagePicker animated:YES completion:^{

    }];


}

- (IBAction)captureImage:(id)sender {

    UIImagePickerController *imagePicker;
    imagePicker = [[UIImagePickerController alloc] init];

    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;

    imagePicker.delegate = self;
    [self presentViewController:imagePicker animated:YES completion:^{

    }];
}

In each method we first create an instance of a UIImagePickerController then we set the source type (either the photo library or camera). Then we set the delegate for the imagePicker to the current view. At last, we present a view controller with animation.

Implementing the Delegate

In the ViewController.h file you can command click the UIPIckerControllerDelegate protocol and it will take you to that class file. There you will find a number of delegates. The delegate method we’ll be using is:

  • (void)imagePickerController:(UIImagePickerController )picker didFinishPickingMediaWithInfo:(NSDictionary )info

so go ahead and add it to the end of the ViewController.m implementation file:


1
2
3
4
5
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{


}

This will let our controller know when an image has been selected. Now fill in the delegate with the following:


1
2
3
4
5
6
7
8
9
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{

    [self dismissViewControllerAnimated:YES completion:^{

}];
    self.imageView.image = [info objectForKey:UIImagePickerControllerOriginalImage];

}

This extra code basically dismisses the view when an object is selected. Then we search the NSDictionary object returned and find the original image and set our imageView outlet to that.

Alright, we have one last thing to do, implement the filter.

Filtering the Image

Ok, I’m not going to get to fancy with this app so we’ll be implementing just one hard coded filter. In a production app you may want to use a plist to store filter types and settings and load them through a picker. These subjects have already been covered on this site so I’ll leave this as a homework assignment for you.

So here is our blank filterImage method:


1
2
3
- (IBAction)filterImage:(id)sender {

}

Now let’s fill it in:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- (IBAction)filterImage:(id)sender {

    CIImage *rawImageData;
rawImageData =[[CIImage alloc] initWithImage:self.imageView.image];

    CIFilter *filter = [CIFilter filterWithName:@"CIDotScreen"];
    [filter setDefaults];

    [filter setValue:rawImageData forKey:@"inputImage"];

    [filter setValue:[NSNumber numberWithFloat:25.00]
          forKey:@"inputWidth"];

    [filter setValue:[NSNumber numberWithFloat:0.00]
          forKey:@"inputAngle"];

    [filter setValue:[NSNumber numberWithFloat:0.70]
          forKey:@"inputSharpness"];



    CIImage *filteredImageData = [filter valueForKey:@"outputImage"];

    UIImage *filteredImage = [UIImage imageWithCIImage:filteredImageData];
self.imageView.image = filteredImage;


}

First we are creating a new CIImage object. This will hold the raw data for the UIImage since a UIImage is not mutable we use the CIImage to perform operations instead.

Then we set our CIImage data from the current UIView Image.

Next we start using the filter. I chose to use the CIDotScreen filter. This is a simulated halftone filter kind of look. You can find a full list of filters on the apple developer site. This also includes the usage of each filter.

next we are setting key value pairs for this particular filter. These input parameters will change depending on the type of filter you use.

Then we reset the CIImage with the filtered image data and create a new UIImage and set the UIImageView to that image.

Now go ahead and run it!

Image3

Image4

The last thing here is if you are simulating the “Capture Image” button will error out and not work but you can still use the Pick Image. One way to add photos to the simulator is to drag and drop a photo to the simulator. This will open up safari, then click and hold on the picture in safari and choose save. Then the photo should be available to your library.

That should be about it. I encourage you go try and implement other filters!

Don’t forget to check out the source code on our github account.

About Joe Hoffman

I am An Electrical Engineer that spends a lot of my off time doing web development and other programming. Currently I am trying to expand my knowledge with iOS and I find that writing tutorials helps me learn more thoroughly as well as provide some useful info to others.

Comments

  1. Awesome right up! Any way this can be filtered in color?

Speak Your Mind

*

css.php
Privacy Policy