4

This is probably very straightforward, but I am not even sure what it's called - which makes googling a bit less useful than usual.

I have a gray scale line drawing with alpha for anti-aliasing effect. This drawing is used as a player token in a game. Currently, I have created a couple of colorized variants (in Photoshop). But I would like to be able to programmatically tint the original image, while preserving the alpha values. I am using Quartz/Core Graphics, and I suspect that there may be some sort of blend that would accomplish the desired effect - but not sure which or even if that's the right approach.

STW
  • 44,917
  • 17
  • 105
  • 161
westsider
  • 4,967
  • 5
  • 36
  • 51
  • Did you ever get this to work? If so, would you mind posting your solution? (I posted a similar question today here: http://stackoverflow.com/questions/14176569/i-want-to-use-quartz-to-make-a-single-color-image-a-different-color) – livingtech Jan 06 '13 at 06:16
  • @livingtech - No, I never did. But I would still like to know if this is possible - with reasonable efficiency. – westsider Jan 07 '13 at 15:38
  • It's definitely possible, and I implemented it in `drawRect:`, so unless you're going to change the tint every frame or something, I don't think you'll run into efficiency problems. See the link I posted for my answer (which might be slightly different from what you were looking for). Actually maybe I should just post another answer here. – livingtech Jan 08 '13 at 16:31

1 Answers1

8

Try this.

ColorChangingImageView.h:

#import <UIKit/UIKit.h>

@interface ColorChangingImageView : UIView
@property (strong, nonatomic) UIImage *image;
@property (strong, nonatomic) UIColor *colorToChangeInto;
@end

ColorChangingImageView.m:

#import "ColorChangingImageView.h"

@implementation ColorChangingImageView

@synthesize image = _image;
@synthesize colorToChangeInto = _colorToChangeInto;

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextScaleCTM(context, 1, -1);
    CGContextTranslateCTM(context, 0, -rect.size.height);

    CGImageRef maskImage = [self.image CGImage];
    CGContextClipToMask(context, rect, maskImage);

    [_colorToChangeInto setFill];
    CGContextFillRect(context, rect);

    //blend mode overlay
    CGContextSetBlendMode(context, kCGBlendModeOverlay);

    //draw the image
    CGContextDrawImage(context, rect, _image.CGImage);
}

Then, to use it:

ColorChangingImageView *iv = [[ColorChangingImageView alloc] initWithFrame:rect];
[iv setBackgroundColor:[UIColor clearColor]]; // might not need this, not sure.
[iv setImage:[UIImage imageNamed:@"image.png"]];
[iv setColorToChangeInto:[UIColor blueColor]];

...or anyway, something very close to that that. Let me know if it works out for you.

You can also play with the second parameter to CGContextSetBlendMode() for slightly different effects.

livingtech
  • 3,570
  • 29
  • 42
  • Thanks. It will be a while before I get a chance to try this out. I have changed jobs - and not getting to do very much iOS coding these days... alas. :-) – westsider Jan 08 '13 at 19:29