Changing UIImage color
Since iOS 7, this is the most simple way of doing it.
Objective-C:
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];[theImageView setTintColor:[UIColor redColor]];
Swift 2.0:
theImageView.image = theImageView.image?.imageWithRenderingMode(.AlwaysTemplate) theImageView.tintColor = UIColor.magentaColor()
Swift 4.0:
theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate) theImageView.tintColor = .magenta
Storyboard:
First configure the image as template ( on right bar - Render as) in your assets. Then the color of the image would be the tint color applied.
This is pretty much the answer above, but slightly shortened. This only takes the image as a mask and does not actually "multiply" or color the image.
Objective C:
UIColor *color = <# UIColor #>; UIImage *image = <# UIImage #>;// Image to mask with UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); CGContextRef context = UIGraphicsGetCurrentContext(); [color setFill]; CGContextTranslateCTM(context, 0, image.size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextClipToMask(context, CGRectMake(0, 0, image.size.width, image.size.height), [image CGImage]); CGContextFillRect(context, CGRectMake(0, 0, image.size.width, image.size.height)); UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
Swift:
let color: UIColor = <# UIColor #> let image: UIImage = <# UIImage #> // Image to mask with UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) let context = UIGraphicsGetCurrentContext() color.setFill() context?.translateBy(x: 0, y: image.size.height) context?.scaleBy(x: 1.0, y: -1.0) context?.clip(to: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), mask: image.cgImage!) context?.fill(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)) let coloredImg = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext()
Another way to tint an image is to simply multiply it by a constant color. Sometimes, this is preferable because it doesn't "lift" the color values in black areas; it keeps the relative intensities in the image the same. Using an overlay as a tint tends to flatten out the contrast.
This is the code I use:
UIImage *MultiplyImageByConstantColor( UIImage *image, UIColor *color ) { CGSize backgroundSize = image.size; UIGraphicsBeginImageContext(backgroundSize); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGRect backgroundRect; backgroundRect.size = backgroundSize; backgroundRect.origin.x = 0; backgroundRect.origin.y = 0; CGFloat r,g,b,a; [color getRed:&r green:&g blue:&b alpha:&a]; CGContextSetRGBFillColor(ctx, r, g, b, a); CGContextFillRect(ctx, backgroundRect); CGRect imageRect; imageRect.size = image.size; imageRect.origin.x = (backgroundSize.width - image.size.width)/2; imageRect.origin.y = (backgroundSize.height - image.size.height)/2; // Unflip the image CGContextTranslateCTM(ctx, 0, backgroundSize.height); CGContextScaleCTM(ctx, 1.0, -1.0); CGContextSetBlendMode(ctx, kCGBlendModeMultiply); CGContextDrawImage(ctx, imageRect, image.CGImage); UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage;}
Swift version
extension UIImage{ static func multiplyImageByConstantColor(image:UIImage,color:UIColor)->UIImage{ let backgroundSize = image.size UIGraphicsBeginImageContext(backgroundSize) let ctx = UIGraphicsGetCurrentContext() var backgroundRect=CGRect() backgroundRect.size = backgroundSize backgroundRect.origin.x = 0 backgroundRect.origin.y = 0 var r:CGFloat var g:CGFloat var b:CGFloat var a:CGFloat color.getRed(&r, green: &g, blue: &b, alpha: &a) CGContextSetRGBFillColor(ctx, r, g, b, a) CGContextFillRect(ctx, backgroundRect) var imageRect=CGRect() imageRect.size = image.size imageRect.origin.x = (backgroundSize.width - image.size.width)/2 imageRect.origin.y = (backgroundSize.height - image.size.height)/2 // Unflip the image CGContextTranslateCTM(ctx, 0, backgroundSize.height) CGContextScaleCTM(ctx, 1.0, -1.0) CGContextSetBlendMode(ctx, .Multiply) CGContextDrawImage(ctx, imageRect, image.CGImage) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage }}