Skip to content

Instantly share code, notes, and snippets.

@lynfogeek
Forked from fabb/UIImage+Colorize.swift
Last active October 20, 2023 15:21
Show Gist options
  • Star 35 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save lynfogeek/4b6ce0117fb0acdabe229f6d8759a139 to your computer and use it in GitHub Desktop.
Save lynfogeek/4b6ce0117fb0acdabe229f6d8759a139 to your computer and use it in GitHub Desktop.
import UIKit
extension UIImage {
// colorize image with given tint color
// this is similar to Photoshop's "Color" layer blend mode
// this is perfect for non-greyscale source images, and images that have both highlights and shadows that should be preserved
// white will stay white and black will stay black as the lightness of the image is preserved
func tint(tintColor: UIColor) -> UIImage {
return modifiedImage { context, rect in
// draw black background - workaround to preserve color of partially transparent pixels
context.setBlendMode(.normal)
UIColor.black.setFill()
context.fill(rect)
// draw original image
context.setBlendMode(.normal)
context.draw(self.cgImage!, in: rect)
// tint image (loosing alpha) - the luminosity of the original image is preserved
context.setBlendMode(.color)
tintColor.setFill()
context.fill(rect)
// mask by alpha values of original image
context.setBlendMode(.destinationIn)
context.draw(self.cgImage!, in: rect)
}
}
// fills the alpha channel of the source image with the given color
// any color information except to the alpha channel will be ignored
func fillAlpha(fillColor: UIColor) -> UIImage {
return modifiedImage { context, rect in
// draw tint color
context.setBlendMode(.normal)
fillColor.setFill()
context.fill(rect)
// context.fillCGContextFillRect(context, rect)
// mask by alpha values of original image
context.setBlendMode(.destinationIn)
context.draw(self.cgImage!, in: rect)
}
}
private func modifiedImage( draw: (CGContext, CGRect) -> ()) -> UIImage {
// using scale correctly preserves retina images
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context: CGContext! = UIGraphicsGetCurrentContext()
assert(context != nil)
// correctly rotate image
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
draw(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
@lynfogeek
Copy link
Author

Updated to Swift 3

@NoiseDesign
Copy link

really good, thank you!

@krbiz
Copy link

krbiz commented Apr 24, 2017

Hi there! Maybe you know, how I can get only red channel information from UIImage?

@jakedunc
Copy link

Thanks man!!

@kmaschke85
Copy link

Works really great, thanks!

@Umity
Copy link

Umity commented Aug 28, 2018

how can i use this?

@BenNathanaelTse
Copy link

that worked, GREAT STUFF!

@OrestM
Copy link

OrestM commented Apr 5, 2019

Thanks! Works very well!

@manishah641
Copy link

thanks so much

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