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