Skip to content

Instantly share code, notes, and snippets.

@iamjason
Last active December 10, 2019 21:59
Show Gist options
  • Save iamjason/a0a92845094f5b210cf8 to your computer and use it in GitHub Desktop.
Save iamjason/a0a92845094f5b210cf8 to your computer and use it in GitHub Desktop.
Swift UIImage extension for tinting images
/**
Usage:
let originalImage = UIImage(named: "cat")
let tintedImage = originalImage.tintWithColor(UIColor(red: 0.9, green: 0.7, blue: 0.4, alpha: 1.0))
*/
extension UIImage {
func tintWithColor(color:UIColor)->UIImage {
UIGraphicsBeginImageContext(self.size)
let context = UIGraphicsGetCurrentContext()
// flip the image
CGContextScaleCTM(context, 1.0, -1.0)
CGContextTranslateCTM(context, 0.0, -self.size.height)
// multiply blend mode
CGContextSetBlendMode(context, kCGBlendModeMultiply)
let rect = CGRectMake(0, 0, self.size.width, self.size.height)
CGContextClipToMask(context, rect, self.CGImage)
color.setFill()
CGContextFillRect(context, rect)
// create uiimage
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
@SammyVimes
Copy link

SammyVimes commented Apr 5, 2018

Swift 3 with cap insets from original image (image will resize the way you set insets):

extension UIImage {

    func tint(with color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, UIScreen.main.scale)
        guard let context = UIGraphicsGetCurrentContext() else { return self }
        
        // flip the image
        context.scaleBy(x: 1.0, y: -1.0)
        context.translateBy(x: 0.0, y: -self.size.height)
        
        // multiply blend mode
        context.setBlendMode(.multiply)
        
        let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context.clip(to: rect, mask: self.cgImage!)
        color.setFill()
        context.fill(rect)
        
        // create UIImage
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else { return self }
        UIGraphicsEndImageContext()
        
        return newImage.resizableImage(withCapInsets: self.capInsets, resizingMode: self.resizingMode)
    }

}

@Blackjacx
Copy link

Blackjacx commented Dec 3, 2018

Omit self when you don't need it:

func setTint(_ color: UIColor) -> UIImage {

    defer { UIGraphicsEndImageContext() }

    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
    guard let context = UIGraphicsGetCurrentContext() else { return self }

    // flip the image
    context.scaleBy(x: 1.0, y: -1.0)
    context.translateBy(x: 0.0, y: -size.height)

    // multiply blend mode
    context.setBlendMode(.multiply)

    let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    context.clip(to: rect, mask: cgImage!)
    color.setFill()
    context.fill(rect)

    // create UIImage
    guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else { return self }

    return newImage
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment