- (UIImage *) changeColorForImage:(UIImage *)image toColor:(UIColor*)color {
UIGraphicsBeginImageContext(image.size);
CGRect contextRect;
contextRect.origin.x = 0.0f;
contextRect.origin.y = 0.0f;
contextRect.size = [image size];
// Retrieve source image and begin image context
CGSize itemImageSize = [image size];
CGPoint itemImagePosition;
itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) );
UIGraphicsBeginImageContext(contextRect.size);
CGContextRef c = UIGraphicsGetCurrentContext();
// Setup shadow
// Setup transparency layer and clip to mask
CGContextBeginTransparencyLayer(c, NULL);
CGContextScaleCTM(c, 1.0, -1.0);
CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [image CGImage]);
// Fill and end the transparency layer
const float* colors = CGColorGetComponents( color.CGColor );
CGContextSetRGBFillColor(c, colors[0], colors[1], colors[2], .75);
contextRect.size.height = -contextRect.size.height;
contextRect.size.height -= 15;
CGContextFillRect(c, contextRect);
CGContextEndTransparencyLayer(c);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Now that I know this simple code, I can even create idiotic methods like:
Now that I know this simple code, I can even create idiotic methods like:
- (UIColor*) oppositeColor:(UIColor*)color {
const float* colors = CGColorGetComponents(color.CGColor);
return [UIColor colorWithRed:1-colors[0] green:1-colors[1] blue:1-colors[2] alpha:1];
}
6 comments:
thanks you so much man, it's exaclt what I was looking for.
Louis.
Very much welcome, glad to help out :)
Hey! This code doesn't properly account for different color spaces of the input UIColor. Specifically, it renders grayscale colors improperly. Here is a modified version that takes the input color space into account.
+ (UIImage*)changeColorForImage:(UIImage *)image toColor:(UIColor*)color
{
UIGraphicsBeginImageContext(image.size);
CGRect contextRect;
contextRect.origin.x = 0.0f;
contextRect.origin.y = 0.0f;
contextRect.size = [image size];
// Retrieve source image and begin image context
CGSize itemImageSize = [image size];
CGPoint itemImagePosition;
itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) );
UIGraphicsBeginImageContext(contextRect.size);
CGContextRef c = UIGraphicsGetCurrentContext();
// Setup shadow
// Setup transparency layer and clip to mask
CGContextBeginTransparencyLayer(c, NULL);
CGContextScaleCTM(c, 1.0, -1.0);
CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [image CGImage]);
// Fill and end the transparency layer
CGColorSpaceRef colorSpace = CGColorGetColorSpace(color.CGColor);
CGColorSpaceModel model = CGColorSpaceGetModel(colorSpace);
const CGFloat* colors = CGColorGetComponents(color.CGColor);
if(model == kCGColorSpaceModelMonochrome)
{
CGContextSetRGBFillColor(c, colors[0], colors[0], colors[0], colors[1]);
}else{
CGContextSetRGBFillColor(c, colors[0], colors[1], colors[2], colors[3]);
}
contextRect.size.height = -contextRect.size.height;
contextRect.size.height -= 15;
CGContextFillRect(c, contextRect);
CGContextEndTransparencyLayer(c);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Hey Ben,
You are right. Under what condition would be you be in (using?) a different color space?
Thanks!
D
Hi Ben,
Code looks great and thanks for the code...
Is it possible to change one complete color [ARGB not transparent] to another color...?
any idea regarding this please share
Thanks,
Spynet
So, I wrote this gist at https://gist.github.com/4353039, with some fixes and removal of unneeded parts. If I broke some use case I'm unaware of, please let me know, but as far as I've tested it it works fine.
Post a Comment