My goal is to change the "ME!" parts color. Either tint only the last 3rd of the image, or replace the blue color with the new color.
Expected result after color change:
Unfortunately neither worked for me. To change the specific color I tried this: LINK, but as the documentation says, this works only without alpha channel!
Then I tried this one: LINK, but this actually does nothing, no tint or anything.
Is there any other way to tint only one part of the color or just replace a specific color?
It turns out to be surprisingly complicated—you’d think you could do it in one pass with CoreGraphics blend modes, but from pretty extensive experimentation I haven’t found such a way that doesn’t mangle the alpha channel or the coloration. The solution I landed on is this:
The reason this works is because of the combination of blend modes. What you’re doing is creating a fully-opaque black-and-white image (step 5), then multiplying it by your final color (step 8), which gives you a fully opaque black-and-your-final-color image. Then, you take the original image, which still has its alpha channel, and draw it with the “destination in” blend mode which takes the color from the black-and-your-color image and the alpha channel from the original image. The result is a tinted image with the original brightness values and alpha channel.
Objective-C
- (UIImage *)createTintedImageFromImage:(UIImage *)originalImage color:(UIColor *)desiredColor {
CGSize imageSize = originalImage.size;
CGFloat imageScale = originalImage.scale;
CGRect contextBounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
UIGraphicsBeginImageContextWithOptions(imageSize, NO /* not opaque */, imageScale); // 2
[[UIColor blackColor] setFill]; // 3a
UIRectFill(contextBounds); // 3b
[originalImage drawAtPoint:CGPointZero]; // 4
UIImage *imageOverBlack = UIGraphicsGetImageFromCurrentImageContext(); // 5
CGContextClear(UIGraphicsGetCurrentImageContext()); // 6
[desiredColor setFill]; // 7a
UIRectFill(contextBounds); // 7b
[imageOverBlack drawAtPoint:CGPointZero blendMode:kCGBlendModeMultiply alpha:1]; // 8
[originalImage drawAtPoint:CGPointZero blendMode:kCGBlendModeDestinationIn alpha:1]; // 9
finalImage = UIGraphicsGetImageFromCurrentContext(); // 10
UIGraphicsEndImageContext();
return finalImage;
}
Swift 4
func createTintedImageFromImage(originalImage: UIImage, desiredColor: UIColor) -> UIImage {
let imageSize = originalImage.size
let imageScale = originalImage.scale
let contextBounds = CGRect(origin: .zero, size: imageSize)
UIGraphicsBeginImageContextWithOptions(imageSize, false /* not opaque */, imageScale) // 2
defer { UIGraphicsEndImageContext() }
UIColor.black.setFill() // 3a
UIRectFill(contextBounds) // 3b
originalImage.draw(at: .zero) // 4
guard let imageOverBlack = UIGraphicsGetImageFromCurrentImageContext() else { return originalImage } // 5
desiredColor.setFill() // 7a
UIRectFill(contextBounds) // 7b
imageOverBlack.draw(at: .zero, blendMode: .multiply, alpha: 1) // 8
originalImage.draw(at: .zero, blendMode: .destinationIn, alpha: 1) // 9
guard let finalImage = UIGraphicsGetImageFromCurrentImageContext() else { return originalImage } // 10
return finalImage
}
There are lots of ways to do this.
Core image filters come to mind as a good way to go. Since the part you want to change is a unique color, you could use the Core image CIHueAdjust filter to shift the hue from blue to red. Only the word you want to change has any color to it, so that's all it would change.
If you had an image with various colors in it and still wanted to replace ALL The colors in the image you could use CIColorCube to map the blue pixels to red without affecting other colors. There was a thread on this board last week with sample code using CIColorCube to force one color to another. Search on CIColorCube and look for the most recent post and you should be able to find it.
If you wanted to limit the change to a specific area of the screen you could probably come up with a sequence of core image filters that would limit your changes to just the target area.
You could also slice out the part you want to change, color edit it using a any of variety of techniques, and then composite it back together.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With