Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I tint an image programmatically on iOS?

I would like to tint an image with a color reference. The results should look like the Multiply blending mode in Photoshop, where whites would be replaced with tint:

alt text

I will be changing the color value continuously.

Follow up: I would put the code to do this in my ImageView's drawRect: method, right?

As always, a code snippet would greatly aid in my understanding, as opposed to a link.

Update: Subclassing a UIImageView with the code Ramin suggested.

I put this in viewDidLoad: of my view controller:

[self.lena setImage:[UIImage imageNamed:kImageName]]; [self.lena setOverlayColor:[UIColor blueColor]]; [super viewDidLoad]; 

I see the image, but it is not being tinted. I also tried loading other images, setting the image in IB, and calling setNeedsDisplay: in my view controller.

Update: drawRect: is not being called.

Final update: I found an old project that had an imageView set up properly so I could test Ramin's code and it works like a charm!

Final, final update:

For those of you just learning about Core Graphics, here is the simplest thing that could possibly work.

In your subclassed UIView:

- (void)drawRect:(CGRect)rect {      CGContextRef context = UIGraphicsGetCurrentContext();      CGContextSetFillColor(context, CGColorGetComponents([UIColor colorWithRed:0.5 green:0.5 blue:0 alpha:1].CGColor)); // don't make color too saturated      CGContextFillRect(context, rect); // draw base      [[UIImage imageNamed:@"someImage.png"] drawInRect: rect blendMode:kCGBlendModeOverlay alpha:1.0]; // draw image } 
like image 777
willc2 Avatar asked Jul 12 '09 23:07

willc2


People also ask

What is tint color in IOS?

Tint color is a "default" or "fallback" color for the application or UIView. As Apple states, "it is the first non-default color in the heirarchy. All subclasses of UIView derive their behavior for tintColor from the base class.".

How do I change the button color of an image programmatically in Swift?

If you are setting the image for a button, just go to attributes inspector and change the button type to system. Then set the image and change the tint color. The color of the image will change.

How do I change the color of an image in SwiftUI?

How to change the color of multicolor SF Symbols in SwiftUI. We can change the color of multicolor symbols by set both renderingMode and foregroundColor . <1> We enable multicolor mode by set .


2 Answers

In iOS7, they've introduced tintColor property on UIImageView and renderingMode on UIImage. To tint an UIImage on iOS7, all you have to do is:

UIImageView* imageView = … UIImage* originalImage = … UIImage* imageForRendering = [originalImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; imageView.image = imageForRendering; imageView.tintColor = [UIColor redColor]; // or any color you want to tint it with 
like image 89
Toland Hon Avatar answered Sep 26 '22 00:09

Toland Hon


First you'll want to subclass UIImageView and override the drawRect method. Your class needs a UIColor property (let's call it overlayColor) to hold the blend color and a custom setter that forces a redraw when the color changes. Something like this:

- (void) setOverlayColor:(UIColor *)newColor {    if (overlayColor)      [overlayColor release];     overlayColor = [newColor retain];    [self setNeedsDisplay]; // fires off drawRect each time color changes } 

In the drawRect method you'll want to draw the image first then overlay it with a rectangle filled with the color you want along with the proper blending mode, something like this:

- (void) drawRect:(CGRect)area {   CGContextRef context = UIGraphicsGetCurrentContext();   CGContextSaveGState(context);    // Draw picture first   //   CGContextDrawImage(context, self.frame, self.image.CGImage);    // Blend mode could be any of CGBlendMode values. Now draw filled rectangle   // over top of image.   //   CGContextSetBlendMode (context, kCGBlendModeMultiply);   CGContextSetFillColor(context, CGColorGetComponents(self.overlayColor.CGColor));         CGContextFillRect (context, self.bounds);   CGContextRestoreGState(context); } 

Ordinarily to optimize the drawing you would restrict the actual drawing to only the area passed in to drawRect, but since the background image has to be redrawn each time the color changes it's likely the whole thing will need refreshing.

To use it create an instance of the object then set the image property (inherited from UIImageView) to the picture and overlayColor to a UIColor value (the blend levels can be adjusted by changing the alpha value of the color you pass down).

like image 23
Ramin Avatar answered Sep 23 '22 00:09

Ramin