web-dev-qa-db-fra.com

Comment changer la couleur d'un UIImage

Je ne veux pas changer la couleur de fond d'un UIImage,
mais plutôt pour changer la couleur de l’ensemble de l’image.

Parce que j'ai des formulaires standard que je peux déplacer de popover à la vue.
Dans mon application, il est possible de bricoler les images en une seule grande image, c'est-à-dire un tableau.
De plus, je veux changer la couleur en blanc marron ou quoi d'autre.

Mais le problème est: je ne peux que changer le backgroundColor
Y a-t-il un moyen de changer la couleur de UIImage?

Merci d'avance

41
Studie
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;
58
Lloyd18

La réponse acceptée est correcte, mais il existe un moyen beaucoup plus facile pour 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
114
skywinder

Pour Swift 3.2 et 4

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

Utilisation :

self.yourImageView.changePngColorTo(color: .red)
5
gamal

Swift 3, xcode 8.1

Voie 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
    }
}

Utilisation

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)

Voie 2. Extension UIImageView

 extension UIImageView {

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

Utilisation

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

Échantillon complet

import UIKit

class ImageView: UIImageView {

    enum ImageColorTransformType {
        case None, ImageExtension, ImageViewExtension
    }

    var imageColorTransformType = ImageColorTransformType.None

}

class ViewController: UIViewController {

    @IBOutlet weak var colorSwitcher: UIButton!

    var imageViews = [ImageView]()

    private var appleImage: UIImage {
        return UIImage(imageName: "Apple")!
    }

    private var redAppleImage: UIImage {
        return UIImage(imageName: "RedApple")!
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        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)

        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) {

                colorSwitcher.setTitle("Original", for: .normal)

                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
                    }
                }

            } else {
                colorSwitcher.setTitle("Template", for: .normal)

                for imageView in imageViews {
                    switch imageView.imageColorTransformType {

                    case .ImageExtension:
                        imageView.image = imageView.image?.imageWithColor(newColor: nil)

                    case .ImageViewExtension:
                        imageView.imageColor = nil

                    case .None:
                        break
                    }
                }
            }
        }
        get {
            return _useOriginalColors
        }
    }

    @IBAction func switchColors(_ sender: Any) {
        useOriginalColors = !useOriginalColors
    }
}


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
    }
}

extension UIImageView {

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

Storyboard

 enter image description here

Résultat

 enter image description here  enter image description here

Détails

Swift 3, xcode 8.1

4
Vasily Bodnarchuk

Vous pouvez également le faire dans Swift avec le code suivant:

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

tintedImage.tintColor = UIColor.redColor()
4
Bob Mosby

Swift 3 + constructeur d'interface (storyboard)

Si vous avez ajouté UIImageView dans le générateur d'interface:

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

myIcon est un point de vente de votre storyboard, ex: @IBOutlet weak var myIcon: UIImageView!

0
lenooh