How would I tint an image programmatically on iOS? How would I tint an image programmatically on iOS? ios ios

How would I tint an image programmatically on iOS?


In iOS7, they've introduced tintColor property on UIImageView and renderingMode on UIImage. To tint an UIImage on iOS7, all you have to do is:

UIImageView* imageView = …UIImage* originalImage = …UIImage* imageForRendering = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];imageView.image = imageForRendering;imageView.tintColor = [UIColor redColor]; // or any color you want to tint it with


First you'll want to subclass UIImageView and override the drawRect method. Your class needs a UIColor property (let's call it overlayColor) to hold the blend color and a custom setter that forces a redraw when the color changes. Something like this:

- (void) setOverlayColor:(UIColor *)newColor {   if (overlayColor)     [overlayColor release];   overlayColor = [newColor retain];   [self setNeedsDisplay]; // fires off drawRect each time color changes}

In the drawRect method you'll want to draw the image first then overlay it with a rectangle filled with the color you want along with the proper blending mode, something like this:

- (void) drawRect:(CGRect)area{  CGContextRef context = UIGraphicsGetCurrentContext();  CGContextSaveGState(context);  // Draw picture first  //  CGContextDrawImage(context, self.frame, self.image.CGImage);  // Blend mode could be any of CGBlendMode values. Now draw filled rectangle  // over top of image.  //  CGContextSetBlendMode (context, kCGBlendModeMultiply);  CGContextSetFillColor(context, CGColorGetComponents(self.overlayColor.CGColor));        CGContextFillRect (context, self.bounds);  CGContextRestoreGState(context);}

Ordinarily to optimize the drawing you would restrict the actual drawing to only the area passed in to drawRect, but since the background image has to be redrawn each time the color changes it's likely the whole thing will need refreshing.

To use it create an instance of the object then set the image property (inherited from UIImageView) to the picture and overlayColor to a UIColor value (the blend levels can be adjusted by changing the alpha value of the color you pass down).


I wanted to tint an image with alpha and I created the following class. Please let me know if you find any problems with it.

I have named my class CSTintedImageView and it inherits from UIView since UIImageView does not call the drawRect: method, like mentioned in previous replies.I have set a designated initializer similar to the one found in the UIImageView class.

Usage:

CSTintedImageView * imageView = [[CSTintedImageView alloc] initWithImage:[UIImage imageNamed:@"image"]];imageView.tintColor = [UIColor redColor];

CSTintedImageView.h

@interface CSTintedImageView : UIView@property (strong, nonatomic) UIImage * image;@property (strong, nonatomic) UIColor * tintColor;- (id)initWithImage:(UIImage *)image;@end

CSTintedImageView.m

#import "CSTintedImageView.h"@implementation CSTintedImageView@synthesize image=_image;@synthesize tintColor=_tintColor;- (id)initWithImage:(UIImage *)image{    self = [super initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];    if(self)    {        self.image = image;        //set the view to opaque        self.opaque = NO;    }    return self;}- (void)setTintColor:(UIColor *)color{    _tintColor = color;    //update every time the tint color is set    [self setNeedsDisplay];}- (void)drawRect:(CGRect)rect{    CGContextRef context = UIGraphicsGetCurrentContext();        //resolve CG/iOS coordinate mismatch    CGContextScaleCTM(context, 1, -1);    CGContextTranslateCTM(context, 0, -rect.size.height);    //set the clipping area to the image    CGContextClipToMask(context, rect, _image.CGImage);    //set the fill color    CGContextSetFillColor(context, CGColorGetComponents(_tintColor.CGColor));    CGContextFillRect(context, rect);        //blend mode overlay    CGContextSetBlendMode(context, kCGBlendModeOverlay);    //draw the image    CGContextDrawImage(context, rect, _image.CGImage);    }@end