1

Is there a way to change the color of an image, without losing the pattern on it ?

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
Dee
  • 1,887
  • 19
  • 47

1 Answers1

6

Try this (category of UIImage):

.h

@interface UIImage (Overlay)

- (UIImage *)imageWithOverlayColor:(UIColor *)color;

@end

.m

#import "UIImage+Overlay.h"

@implementation UIImage (Overlay)

- (UIImage *)imageWithOverlayColor:(UIColor *)color
{        
    CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);

    if (UIGraphicsBeginImageContextWithOptions) {
        CGFloat imageScale = 1.0f;
        if ([self respondsToSelector:@selector(scale)])  // The scale property is new with iOS4.
            imageScale = self.scale;
        UIGraphicsBeginImageContextWithOptions(self.size, NO, imageScale);
    }
    else {
        UIGraphicsBeginImageContext(self.size);
    }

//    [self drawInRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, self.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextSetBlendMode(context, kCGBlendModeMultiply);
       CGContextDrawImage(context, rect, self.CGImage);
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextClipToMask(context, rect, self.CGImage);
    CGContextFillRect(context, rect);   

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end

Call it like this:

UIImage *image = [UIImage imageNamed:@"image.png"]; 
image = [image imageWithOverlayColor:[UIColor redColor]];

Before and after images:

vakio
  • 3,134
  • 1
  • 22
  • 46
  • If you don't like the result you can try a different blend mode. – vakio Jan 27 '12 at 11:12
  • When ever user changes the color of an image I am calling this method: UIImage *coloreImage = [self imageWithOverlayColor:color]; subLayer.contents = (id) coloreImage.CGImage; and I am giving the return image to CGLayer. I have tried it with different blend modes even though the result is same. – Dee Jan 27 '12 at 12:01
  • Are you using it as a category, and does your image contain an image from the start? It works for me. Example: `UIImage *image = [UIImage imageNamed:@"image.png"]; image = [image imageWithOverlayColor:[UIColor redColor]];` – vakio Jan 27 '12 at 12:32
  • It is changing the color of an image now, but I am loosing the patter on it. How can I change the image color without disturbing the patter on it? – Dee Feb 01 '12 at 06:53
  • See my updated implementation. Note that of course, the image needs to be a transparent png or gif if you want to keep the edges. – vakio Feb 01 '12 at 09:09
  • Your solution is working, when my image doesn't have any color(transparent). what if I need change red color image to transparent one or to some other color? – Dee Feb 02 '12 at 04:45
  • To change to another color just put another color instead of redColor. You mean how to convert to greyscale? Here is a question for that: http://stackoverflow.com/questions/1298867/convert-image-to-grayscale. – vakio Feb 02 '12 at 08:35
  • By default take red color image & use your code and change the color of it, because of hue I am unable to set the selected color to it. What ever the color it is, its getting displayed as dark color. – Dee Feb 03 '12 at 10:39
  • If it's too dark, maybe use `kCGBlendModeScreen` instead or something else. List of blendmodes: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/tdef/CGBlendMode – vakio Feb 03 '12 at 10:48
  • Are you available in chat room? – Dee Feb 03 '12 at 10:56
  • kCGBlendModeHue,kCGBlendModeColor both are giving me some good results. – Dee Feb 03 '12 at 11:40