44

I'm receiving image from a server, then based on a color chosen by the user, the image color will be changed.

I tried the following :

_sketchImageView.image = [_sketchImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[_sketchImageView setTintColor:color];

i got the opposite of my goal (the white color outside UIImage is colored with the chosen color).

what is going wrong?

i need to do the same in this question,the provided solution doesn't solve my case. How can I change image tintColor in iOS and WatchKit

Community
  • 1
  • 1
user2168496
  • 492
  • 1
  • 4
  • 11
  • If you want to fill image with some color you need more advanced solution. Like this: https://github.com/mxcl/UIImageWithColor – orkenstein Feb 10 '15 at 09:19
  • i think you need the effect of background color , try `[_sketchImageView setBackgroundColor: color]` – Saif Feb 10 '15 at 09:22
  • i tried this solution before and it gives the same result. //UIImage *img = [UIImage resizableImageWithColor:color cornerRadius:10]; // UIImage *img = [UIImage imageWithColor:color size:CGSizeMake(20, 20)]; UIImage *img = [UIImage imageWithColor:color]; _sketchImageView.image=img; – user2168496 Feb 10 '15 at 09:36
  • @saif [_sketchImageView setBackgroundColor: [UIColor clearColor]]; _sketchImageView.image = [_sketchImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [_sketchImageView setTintColor:color]; gives me the same result – user2168496 Feb 10 '15 at 09:39

14 Answers14

63

Try to generate new image for yourself

UIImage *newImage = [_sketchImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(image.size, NO, newImage.scale);
[yourTintColor set];
[newImage drawInRect:CGRectMake(0, 0, image.size.width, newImage.size.height)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

_sketchImageView.image = newImage;

And use it.

Good luck

======= UPDATE =======

This solution will only change color of all pixel's image.

Example: we have a book image: http://pngimg.com/upload/book_PNG2113.png

enter image description here

And after running above code (exp: TintColor is RED). We have:

enter image description here

SO: how your image is depends on how you designed it

Tony
  • 4,311
  • 26
  • 49
  • thanx a lot, lets say that i have a book image, this solution colored the image outside the book borders.. i want the opposite,i.e the book itself to be colored. any idea why is this happening? – user2168496 Feb 11 '15 at 08:08
  • I think you need to re-design your book image. I've just edited my post. See it – Tony Feb 11 '15 at 08:34
  • Yeah.yessss.. i tried your image and it works fine :) i really appreciate – user2168496 Feb 11 '15 at 08:48
  • didn't work for me, I prefer this answer : http://stackoverflow.com/questions/19274789/how-can-i-change-image-tintcolor-in-ios-and-watchkit?noredirect=1&lq=1 – NGG Dec 07 '16 at 07:18
25

In Swift you can use this extension: [Based on @VietHung's objective-c solution]

Swift 5:

extension UIImage {
      func imageWithColor(color: UIColor) -> UIImage? {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()
        image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

Previous Swift version:

extension UIImage {
    func imageWithColor(color: UIColor) -> UIImage? {
        var image = imageWithRenderingMode(.AlwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()
        image.drawInRect(CGRect(x: 0, y: 0, width: size.width, height: size.height))
        image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
user1039695
  • 981
  • 11
  • 20
Mejdi Lassidi
  • 999
  • 10
  • 22
18

In swift 2.0 you can use this

let image = UIImage(named:"your image name")?.imageWithRenderingMode(.AlwaysTemplate)
let yourimageView.tintColor = UIColor.redColor()
yourimageView.image = image

In swift 3.0 you can use this

let image = UIImage(named:"your image name")?.withRenderingMode(.alwaysTemplate)
let yourimageView.tintColor = UIColor.red
yourimageView.image = image
MAhipal Singh
  • 4,745
  • 1
  • 42
  • 57
Ruchin Somal
  • 1,073
  • 12
  • 14
  • 2
    For Swift 3.0, you'll want to use withRenderingMode, not imageWithRenderingMode. – Joe Mar 22 '17 at 03:54
6

Try something like this

UIImage *originalImage = _sketchImageView.image
UIImage *newImage = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,50,50)]; // your image size
imageView.tintColor = [UIColor redColor];  // or whatever color that has been selected
imageView.image = newImage;
_sketchImageView.image = imageView.image;

Hope this helps.

Gismay
  • 784
  • 9
  • 17
5

In Swift 3.0 you can use this extension: [Based on @VietHung's objective-c solution]

extension UIImage {
    func imageWithColor(_ color: UIColor) -> UIImage? {
        var image = imageWithRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()
        image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
odemolliens
  • 2,581
  • 2
  • 32
  • 34
3

For Swift 3.0, I made a custom subclass of UIImageView called TintedUIImageView. Now the image uses whatever tint color is set in interface builder or code

class TintedUIImageView: UIImageView {

    override func awakeFromNib() {
        if let image = self.image {
            self.image = image.withRenderingMode(.alwaysTemplate)
        }
    }
}
tylerwalker
  • 91
  • 1
  • 3
  • Welcome to SO! Your reply looks like a comment rather than an answer. Once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment](http://stackoverflow.com/help/privileges/comment) on any post. Also check this [what can I do instead](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). If you intended to Answer, read this [how-to-answer](http://stackoverflow.com/help/how-to-answer) to follow the SO guidelines. – thewaywewere May 05 '17 at 19:55
2

You can try:

 _sketchImageView.image = [self imageNamed:@"imageName" withColor:[UIColor blackColor]];

 - (UIImage *)imageNamed:(NSString *)name withColor:(UIColor *)color
 {
     // load the image
     //NSString *name = @"badge.png";
     UIImage *img = [UIImage imageNamed:name];

     // begin a new image context, to draw our colored image onto
     UIGraphicsBeginImageContext(img.size);

     // get a reference to that context we created
     CGContextRef context = UIGraphicsGetCurrentContext();

     // set the fill color
     [color setFill];

    // translate/flip the graphics context (for transforming from CG* coords to UI* coords
    CGContextTranslateCTM(context, 0, img.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    // set the blend mode to color burn, and the original image
    CGContextSetBlendMode(context, kCGBlendModeColorBurn);
    CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
    CGContextDrawImage(context, rect, img.CGImage);

    // set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
    CGContextClipToMask(context, rect, img.CGImage);
    CGContextAddRect(context, rect);
    CGContextDrawPath(context,kCGPathFill);

    // generate a new UIImage from the graphics context we drew onto
    UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //return the color-burned image
    return coloredImg;
}
gabriel
  • 2,351
  • 4
  • 20
  • 23
  • this code gives CGContextDrawImage: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update. any idea plz? – user2168496 Feb 10 '15 at 12:09
  • Check if your UIImageView instance isn't blank. If the method is not being called against an empty UIIMageView. – gabriel Feb 10 '15 at 12:15
  • yes there is an image,the image is displayed in the imageview then after the user select color,i want its color to be changed – user2168496 Feb 10 '15 at 12:47
  • Could you try the method I suggested on some isolated environment? Like an empty project and hardcode the color and image, just to be sure that error message is not related with this method, but with something else that we cannot see (we have just few lines of your code). Because I tried it and works without any error message. – gabriel Feb 10 '15 at 12:52
  • Yes thanx, i did,, but this solution gives the same result mentioned in the question. to have better understanding for my case imagine that you have imageview contains image for Dress, i want the color of the dress to change based on a color selected by the user.. any idea? – user2168496 Feb 10 '15 at 13:21
1

Try setting the tint color on the superview of the image view. E.g. [self.view setTintColor:color];

Micky
  • 5,578
  • 7
  • 31
  • 55
1

in Swift 4 you can simply make an extension like that:

import UIKit

extension UIImageView {

    func tintImageColor(color: UIColor) {
        guard let image = image else { return }
        self.image = image.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
        self.tintColor = color
    }

}
Julien Kode
  • 5,010
  • 21
  • 36
1

- SWIFT 4

extension UIImage {
    func imageWithColor(_ color: UIColor) -> UIImage? {
        var image: UIImage? = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()
        image?.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
0

Here's how I apply and use tints in IOS 9 with Swift.

//apply a color to an image
//ref - http://stackoverflow.com/questions/28427935/how-can-i-change-image-tintcolor
//ref - https://www.captechconsulting.com/blogs/ios-7-tutorial-series-tint-color-and-easy-app-theming
func getTintedImage() -> UIImageView {

    var image     : UIImage;
    var imageView : UIImageView;

    image = UIImage(named: "someAsset")!;
    let size  : CGSize = image.size;
    let frame : CGRect = CGRectMake((UIScreen.mainScreen().bounds.width-86)/2, 600, size.width, size.height);

    let redCover : UIView = UIView(frame: frame);

    redCover.backgroundColor = UIColor.redColor();
    redCover.layer.opacity = 0.75;

    imageView       = UIImageView();
    imageView.image = image.imageWithRenderingMode(UIImageRenderingMode.Automatic);

    imageView.addSubview(redCover);

    return imageView;
}
J-Dizzle
  • 4,861
  • 4
  • 40
  • 50
0

One thing you can do is, just add your images to Assets folder in XCode and then change the rendering mode to Template Image, so whenever you change the tint color of UIImageView, it will automatically makes change to image.

Check this link out -> https://www.google.co.in/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwiM0YXO0ejTAhUIQ48KHfGpBpgQjRwIBw&url=https%3A%2F%2Fkrakendev.io%2Fblog%2F4-xcode-asset-catalog-secrets-you-need-to-know&psig=AFQjCNGnAzVn92pCqM8612o1R0J9q1y7cw&ust=1494619445516498

0
let image = UIImage(named: "i m a g e   n a m e")?.withRenderingMode(.alwaysTemplate)
imageView.tintColor = UIColor.white // Change to require color 
imageView.image = image
Hemang
  • 26,840
  • 19
  • 119
  • 186
-2

Try this

iOS 13.4 and above

UIImage *image = [UIImage imageNamed:@"placeHolderIcon"];
[image imageWithTintColor:[UIColor whiteColor] renderingMode: UIImageRenderingModeAlwaysTemplate];