How to change the color of an UIImage

IosUiimageUicolor

Ios Problem Overview


I want not to change the backgroundColor of an UIImage,
but rather to change the color of the whole image.

Because I have got standard forms which I can move from popover to the view.
In my App it is possible to tinker the images to one big image, i.e a table.
Moreover I want change the color to white brown or what else.

But the problem is: I can only change the backgroundColor
Is there any way to change the color of the UIImage?

Thank you in advance

Ios Solutions


Solution 1 - Ios

The accepted answer is correct, but there is a much more easy way for UIImageView:

Obj-C:

UIImage *image = [UIImage imageNamed:@"foo.png"];
theImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];

Swift 2:

let theImageView = UIImageView(image: UIImage(named:"foo")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate))
theImageView.tintColor = UIColor.redColor()

Swift 3:

let theImageView = UIImageView(image: UIImage(named:"foo")!.withRenderingMode(.alwaysTemplate))
theImageView.tintColor = UIColor.red

Solution 2 - Ios

UIImage *image = [UIImage imageNamed:@"triangle.png"];

CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToMask(context, rect, image.CGImage);
CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImage *flippedImage = [UIImage imageWithCGImage:img.CGImage 
                                            scale:1.0 orientation: UIImageOrientationDownMirrored];

yourUIImageView.image = flippedImage;

Solution 3 - Ios

For swift 3.2 and 4

extension UIImageView{
    func changePngColorTo(color: UIColor){
        guard let image =  self.image else {return}
        self.image = image.withRenderingMode(.alwaysTemplate)
        self.tintColor = color
    }
}

Use :

self.yourImageView.changePngColorTo(color: .red)

Solution 4 - Ios

Details

  • Xcode 10.2.1 (10E1001), Swift 5

Way 1. Extension UIImage

source: https://stackoverflow.com/a/40177870/4488252

extension UIImage {
    
    convenience init?(imageName: String) {
        self.init(named: imageName)
        accessibilityIdentifier = imageName
    }
    
    // https://stackoverflow.com/a/40177870/4488252
    func imageWithColor (newColor: UIColor?) -> UIImage? {
        
        if let newColor = newColor {
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            
            let context = UIGraphicsGetCurrentContext()!
            context.translateBy(x: 0, y: size.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.setBlendMode(.normal)
            
            let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            context.clip(to: rect, mask: cgImage!)
            
            newColor.setFill()
            context.fill(rect)
            
            let newImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            newImage.accessibilityIdentifier = accessibilityIdentifier
            return newImage
        }
        
        if let accessibilityIdentifier = accessibilityIdentifier {
            return UIImage(imageName: accessibilityIdentifier)
        }
        
        return self
    }
}

Usage

let imageView = UIImageView(frame: CGRect(x: 40, y: 250, width: 40, height: 40))
view.addSubview(imageView)
// Set color
imageView.image = UIImage(imageName: "Apple")?.imageWithColor(newColor: UIColor.blue)
// Reset color
//imageView.image = imageView.image?.imageWithColor(newColor: nil)

Way 2. Extension UIImageView

extension UIImageView {
    
    var imageColor: UIColor? {
        set (newValue) {
            guard let image = image else { return }
            if newValue != nil {
                self.image = image.withRenderingMode(.alwaysTemplate)
                tintColor = newValue
            } else {
                self.image = image.withRenderingMode(.alwaysOriginal)
                tintColor = UIColor.clear
            }
        }
        get { return tintColor }
    }
}

Usage

let imageView = UIImageView(frame: CGRect(x: 40, y: 250, width: 40, height: 40))
view.addSubview(imageView)
imageView.image = UIImage(imageName: "Apple")
// Set color
imageView.imageColor = UIColor.green
// Reset color
//imageView.imageColor = nil

Full sample

> Do not forget to paste here all code which placed above

import UIKit

class ImageView: UIImageView {
    enum ImageColorTransformType {
        case none, imageExtension, imageViewExtension
    }
    var imageColorTransformType = ImageColorTransformType.none
}

class ViewController: UIViewController {
    
    weak var colorSwitchButton: UIBarButtonItem?
    
    private var imageViews = [ImageView]()
    private var appleImage: UIImage { return UIImage(imageName: "apple")! }
    private var redAppleImage: UIImage { return UIImage(imageName: "red_apple")! }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        createNewImageView(x: 40, y:100, image:appleImage, imageColorTransformType: .none)
        createNewImageView(x: 100, y:100, image:appleImage, imageColorTransformType: .imageExtension)
        createNewImageView(x: 160, y:100, image:appleImage, imageColorTransformType: .imageViewExtension)
        
        createNewImageView(x: 40, y:160, image:redAppleImage, imageColorTransformType: .none)
        createNewImageView(x: 100, y:160, image:redAppleImage, imageColorTransformType: .imageExtension)
        createNewImageView(x: 160, y:160, image:redAppleImage, imageColorTransformType: .imageViewExtension)
        
        let buttonItem = UIBarButtonItem(title: "switch", style: .plain, target: self,
                                         action: #selector(colorSwitchButtonTouchedUpInside(_:)))
        navigationItem.rightBarButtonItem = buttonItem
        colorSwitchButton = buttonItem
        useOriginalColors = false
    }
    
    private func createNewImageView(x:CGFloat, y: CGFloat, image: UIImage, imageColorTransformType: ImageView.ImageColorTransformType) {
        let imageView = ImageView(frame: CGRect(x: x, y: y, width: 40, height: 40))
        imageView.image = image
        imageView.imageColorTransformType = imageColorTransformType
        imageViews.append(imageView)
        view.addSubview(imageView)
    }
    
    private var _useOriginalColors = false
    private var useOriginalColors: Bool {
        set(value) {
            _useOriginalColors = value
            if (value) {
                navigationItem.title = "Original colors"
                for imageView in imageViews {
                    switch imageView.imageColorTransformType {
                    case .imageExtension: imageView.image = imageView.image?.imageWithColor(newColor: nil)
                    case .imageViewExtension: imageView.imageColor = nil
                    case .none: break
                    }
                }
            } else {
                navigationItem.title = "Template colors"
                for imageView in imageViews {
                    switch imageView.imageColorTransformType {
                    case .imageExtension: imageView.image = imageView.image?.imageWithColor(newColor: UIColor.blue)
                    case .imageViewExtension: imageView.imageColor = UIColor.green
                    case .none: break
                    }
                }
            }
        }
        get { return _useOriginalColors }
    }
    
    @objc func colorSwitchButtonTouchedUpInside(_ sender: Any) { useOriginalColors = !useOriginalColors }
}

Storyboard

enter image description here

Result

enter image description here enter image description here

Solution 5 - Ios

You can also do this in swift with the following code:

// language: Swift
let tintedImage = UIImageView(image: UIImage(named:"whatever")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate))

tintedImage.tintColor = UIColor.redColor()

Solution 6 - Ios

Swift + Interface builder (storyboard)

If you added the UIImageView in the interface builder:

myIcon.image = myIcon.image!.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
myIcon.tintColor = UIColor.red // your color

where myIcon is an outlet from your storyboard, ex: @IBOutlet weak var myIcon: UIImageView!

Solution 7 - Ios

Change the color of the image in UIImageView:

public extension UIImageView {
    func tintImage(color: UIColor) {
        image = image?.tint(color: color)
    }
}

Just call the method:

imageView.tintImage(color: .red)

Solution 8 - Ios

To add to skywinder's answer

You can also do this on a button:

UIImage *image = [UIImage imageNamed:@"foo.png"];
[myButton setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
[myButton setTintColor:[UIColor redColor]];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStudieView Question on Stackoverflow
Solution 1 - IosskywinderView Answer on Stackoverflow
Solution 2 - IosLloyd18View Answer on Stackoverflow
Solution 3 - IosgamalView Answer on Stackoverflow
Solution 4 - IosVasily BodnarchukView Answer on Stackoverflow
Solution 5 - IosBob MosbyView Answer on Stackoverflow
Solution 6 - IoslenoohView Answer on Stackoverflow
Solution 7 - IosUmair AliView Answer on Stackoverflow
Solution 8 - IosdevjmeView Answer on Stackoverflow