Color Picker for iPhone/iPad

In this post lets discuss how a simple color picker can be implemented and used in general.

Some Important info:

The color picker is very simple tool and designed especially keeping iPhone in mind, even-though you can use it for iPad. We are using an image source for the target objective, here user selects or points a pixel space in the image source, our code reads the RGB values of that pixel.

Design:

The design is made keep in mind two things:

1. Every developer must be able reuse the source code.

2. Developer can easily change Graphics as per the custom requirements.

Technical Design:

Lets talk on how to get the color from the picker and give it to a delegate.

We have a  protocol declared as follows: (in CRColorPicker.h) file

@protocol CRColorPickerDelegate <NSObject>

-(void)selectedColor:(UIColor*)inColor fromColorPicker:(CRColorPicker *)inColorPicker;

@end

You might have already observed, the protocol is compulsory, the object who uses this must implement the delegate method.

CRColorPicker class

In this class we do implement almost everything…we will handle touch events, calculate the color value for a given CGPoint etc etc…

Please note that this sample doesn’t include the existing UISlider component, instead we uses a set of two images, which acts as the two parts of the slider, the body and the slider knob.

The CRColorPicker class, a subclass of UIView looks like this:

@interface CRColorPicker : UIView {

UIImageView *sourceColorImageView; //The imageview from where we pick the color source

id <CRColorPickerDelegate> delegate; //The delegate

UIColor *currentColor; //the current color picked

UIImageView *knobView;  //the knob slider

}

Here we create an instance of UIImageView which holds the Color Picker source. Another UIImageView object represents the slider knob, so that the user can slide the knob across the color source ImageView. The idea behind this is, wherever the knob slider moves, we pick the point with respect to its superview (i.e CRColorPicker ) and the corresponding point in the color source image is a reference point to pick the color.

Moving the knob: Since the knob is again a UIImageView object (knobView), moving it across within the CRColorPicker is very easy. Just handle touch events methods, calculate the new frame of the knob, thats it.

When and how to calculate the color?

Now everything is ready. We have to call a method which picks the UIColor from the source color image.So we make sure that whenever the user slides the knob, we call this method, also as the touch event ends, call again the method.Note that [self changeColor]; is called on both touchesMoved and touchesEnded method.The changeColor method calculates the new point user selected and the respective color.

-(void)changeColor{

double sliderValue = CGRectGetMidX(self.knobView.frame);

CGPoint point = CGPointMake(sliderValue,5);

UIColor *colorSelected = [self pixelColorAt:point colorSource:self.sourceColorImageView.image];

CGRect newFrame = self.knobView.frame;

if([self.delegate respondsToSelector:@selector(selectedColor:fromColorPicker:)]){

[self.delegate selectedColor:colorSelected fromColorPicker:self];

}

self.currentColor = colorSelected;

}

Make sure you have implemented the delegate method in your controller class and also ensure you have set that controller as delegate of the class CRColorPicker.

Reading the pixel RGB values for  a given point: 

-(UIColor*)pixelColorAt:(CGPoint)point colorSource:(UIImage*)inImage;{

UIColor* color = nil;

// Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue

CGImageRef srcImage = inImage.CGImage;

CGContextRef cgctx = [self createARGBBitmapContextFromImage:srcImage];

if (cgctx == NULL) { return nil; /* error */ }

size_t w = CGImageGetWidth(srcImage);

size_t h = CGImageGetHeight(srcImage);

CGRect rect = {{0,0},{w,h}}; 

// Draw the image to the bitmap context. Once we draw, the memory 

// allocated for the context for rendering will then contain the 

// raw image data in the specified color space.

CGContextDrawImage(cgctx, rect, srcImage); 

// Now we can get a pointer to the image data associated with the bitmap

// context.

unsigned char* data = CGBitmapContextGetData (cgctx);

if (data != NULL) {

//offset locates the pixel in the data from x,y. 

//4 for 4 bytes of data per pixel, w is width of one row of data.

int offset = 4*((w*round(point.y))+round(point.x));

int alpha =  data[offset]; 

int red = data[offset+1]; 

int green = data[offset+2]; 

int blue = data[offset+3]; 

// NSLog(@”offset: %i colors: RGB A %i %i %i  %i”,offset,red,green,blue,alpha);

color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];

}

// When finished, release the context

CGContextRelease(cgctx); 

// Free image data memory for the context

if (data) { free(data); }

return color;

}

Here in this tutorial, we will use the color to set the background view of the UIView associated with the controller. And we have set the CRColorPicker view in the nib file itself, otherwise you can create an instance of the same and add it to the view programmatically.

This is how the sample looks:

Source code is here, please write us incase any questions. Use this source code wherever required and build a great iPhone application.

Please write your feedback, comments, suggestions.

Thanks for reading this tutorial, hope this helps you. In next tutorial lets discuss how we used this color picker  in iPhone “Font View“, a free application made for the developers.

Regards

i-CRG Labs iPhone Team

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: