I'm trying to find out how to change the color/hue of a UIImage. I found out that iOS5 has a lot of image filters, but I have hard time finding documentation on the proper use of the CIColorMatrix
filter.
-(void)doCIColorMatrixFilter
{
//does not work, returns nil image
CIImage* inputImage = [CIImage imageWithCGImage:[[UIImage imageNamed:@"button.jpg"]CGImage]];
CIFilter *myFilter;
NSDictionary *myFilterAttributes;
myFilter = [CIFilter filterWithName:@"CIColorMatrix"];
[myFilter setDefaults];
myFilterAttributes = [myFilter attributes];
[myFilterAttributes setValue:inputImage forKey:@"inputImage"];
//How to set up attributes?
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *ciimage = [myFilter outputImage];
CGImageRef cgimg = [context createCGImage:ciimage fromRect:[ciimage extent]];
UIImage *uimage = [UIImage imageWithCGImage:cgimg scale:1.0f orientation:UIImageOrientationUp];
[imageView setImage:uimage];
CGImageRelease(cgimg);
}
What code goes into the dictionary for this filter?
One month later ...
This is an example of CIColorMatrix
setting all its parameters :)
-(void)doCIColorMatrixFilter
{
// Make the input image recipe
CIImage *inputImage = [CIImage imageWithCGImage:[UIImage imageNamed:@"facedetectionpic.jpg"].CGImage]; // 1
// Make the filter
CIFilter *colorMatrixFilter = [CIFilter filterWithName:@"CIColorMatrix"]; // 2
[colorMatrixFilter setDefaults]; // 3
[colorMatrixFilter setValue:inputImage forKey:kCIInputImageKey]; // 4
[colorMatrixFilter setValue:[CIVector vectorWithX:1 Y:1 Z:1 W:0] forKey:@"inputRVector"]; // 5
[colorMatrixFilter setValue:[CIVector vectorWithX:0 Y:1 Z:0 W:0] forKey:@"inputGVector"]; // 6
[colorMatrixFilter setValue:[CIVector vectorWithX:0 Y:0 Z:1 W:0] forKey:@"inputBVector"]; // 7
[colorMatrixFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:1] forKey:@"inputAVector"]; // 8
// Get the output image recipe
CIImage *outputImage = [colorMatrixFilter outputImage]; // 9
// Create the context and instruct CoreImage to draw the output image recipe into a CGImage
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]]; // 10
// Draw the image in screen
UIImageView *imageView2 = [[UIImageView alloc] initWithImage:[UIImage imageWithCGImage:cgimg]];
CGRect f = imageView2.frame;
f.origin.y = CGRectGetMaxY(imageView.frame);
imageView2.frame = f;
[self.view addSubview:imageView2];
}
So this is what the sample does:
In 1
we create the ciimage, if you are getting nil there then make sure you are passing the right UIImage/CGImage or path.
In 2
create the filter, you know this :)
In 3
set the filter parameters to its defaults, CoreImage Programming guide suggests we should do this although (I haven't experimented any strange/bad things if avoided.)
In 4
set the input ciimage
From 5
through 8
we set the parameters. For example I made the red vector {1,1,1,0} so the image looks reddish. 6
, 7
and 8
and not necessary here since their values are the same as the defaults (remember we called -setDefaults
?) but for educational purposes I guess they are fine :)
In 9
set the output image, although is not drawn yet.
Finally in 10
you tell CoreImage to draw the output image into a CGImage, and we put that CGImage into an UIImage and it inside an UIImageView.
This is the result (I used the same image as this tutorial):
Hope it helps.
Just a Swift example with a chain to add to above answer by nacho4d
var output = CIFilter(name: "CIColorControls")
output.setValue(ciImage, forKey: kCIInputImageKey)
output.setValue(1.8, forKey: "inputSaturation")
output.setValue(0.01, forKey: "inputBrightness")
filter = CIFilter(name: "CIColorMatrix")
filter.setDefaults()
filter.setValue(output.outputImage, forKey: kCIInputImageKey)
filter.setValue(CIVector(x: 1, y: 0.1, z: 0.1, w: 0), forKey: "inputRVector")
filter.setValue(CIVector(x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
filter.setValue(CIVector(x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")
Note that the defaults are 1,0,0 0,1,0 and 0,0,1 respectively for RGB and if you want to make it more red you would set the inputRVector to 1,1,1 and leave the others the same (as this multiples the blue and green components by red values)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With