Image processing in iPhone applications is really simple. This tutorial will show you how to use Quartz 2D functions to obtain the actual pixel data from a CGImage object and how to create new modified image.

Open Xcode and create a new project from the View-based Application template. Add some existing image you want to use in application to Resources folder (Add->Existing Files…), in tutorial I use image named storm-at-sea.jpg. Open YouProjectName_ViewController.xib in Interface builder, add UIImageView and UISwitch to UIView by dragging them from the Library panel. Set the image property of an UIImageView to name of your image and set UISwitch State property to Off.

You have now created application interface. Build and Run will show your image and switch that is set to Off at the moment.

Let’s write some code that will process image when user change switch value. Open YouProjectName_ViewController.h and define IBAction toggleSwitch and properties for UIImageView and UISwitch.

#import <UIKit/UIKit.h>

@interface YouProjectName_ViewController : UIViewController {


- (IBAction) toggleSwitch: (id) sender;

@property (nonatomic, retain) IBOutlet UIImageView *theImage;
@property (nonatomic, retain) IBOutlet UISwitch *theSwitch;


In YouProjectName_ViewController.m synthesize UIImageView and UISwitch.

@synthesize theImage;
@synthesize theSwitch;

Define IBAction named toggleSwitch. This is where we check UISwitch state. If switch state is On we need to process image, otherwise we’ll set UIImageView Image property back to original image.

- (IBAction) toggleSwitch: (id) sender {


Add following code to IBAction toggleSwitch. If switch state is On we create CGImageRef named sourceImage from our current image. CFDataRef theData is image data we need to get pixel RGBA array pixelData out of image. The for loop statement loops through this pixel array which stores a color for each pixel and process image. In this tutorial we’ll create simple “night mode” effect, so we check is pixel value of green color minus 128 greater than zero. If so, we’ll set red and blue channel value to value of green channel minus 128, otherwise we’ll set their values to zero. As we process image data in loop we create Quartz bitmap graphics contexts using the function CGBitmapContextCreate. After we create new image from this context, we release context and image data and we set UIImageView image property to this new image. If switch state is set to Off, set UIImageView to original image.

if (theSwitch.on){

	CGImageRef sourceImage = theImage.image.CGImage;

	CFDataRef theData;
	theData = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage));

	UInt8 *pixelData = (UInt8 *) CFDataGetBytePtr(theData);

	int dataLength = CFDataGetLength(theData);

	int red = 0;
	int green = 1;
	int blue = 2;

	for (int index = 0; index < dataLength; index += 4) {
		if (pixelData[index + green] - 128 > 0) {
			pixelData[index + red] = pixelData[index + green] - 128;
			pixelData[index + blue] = pixelData[index + green] - 128;
		} else {
			pixelData[index + red] = 0;
			pixelData[index + blue] = 0;

	CGContextRef context;
	context = CGBitmapContextCreate(pixelData,

	CGImageRef newCGImage = CGBitmapContextCreateImage(context);
	UIImage *newImage = [UIImage imageWithCGImage:newCGImage];


	theImage.image = newImage;

} else {
	theImage.image = [UIImage imageNamed:@"storm-at-sea.jpg"];

Open YouProjectName_ViewController.xib in Interface builder again and make connections between the code and the interface. When you run the application you’ll see original image, as you change switch value image will process our simple “night mode” effect.

Thanks for reading!