Skip to content

Instantly share code, notes, and snippets.

@omz
Created July 24, 2011 01:40
Show Gist options
  • Star 97 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save omz/1102091 to your computer and use it in GitHub Desktop.
Save omz/1102091 to your computer and use it in GitHub Desktop.
Creating arbitrarily-colored icons from a black-with-alpha master image (iOS)
// Usage example:
// input image: http://f.cl.ly/items/3v0S3w2B3N0p3e0I082d/Image%202011.07.22%2011:29:25%20PM.png
//
// UIImage *buttonImage = [UIImage ipMaskedImageNamed:@"UIButtonBarAction.png" color:[UIColor redColor]];
// .h
@interface UIImage (IPImageUtils)
+ (UIImage *)ipMaskedImageNamed:(NSString *)name color:(UIColor *)color;
@end
// .m
@implementation UIImage (IPImageUtils)
+ (UIImage *)ipMaskedImageNamed:(NSString *)name color:(UIColor *)color
{
UIImage *image = [UIImage imageNamed:name];
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale);
CGContextRef c = UIGraphicsGetCurrentContext();
[image drawInRect:rect];
CGContextSetFillColorWithColor(c, [color CGColor]);
CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
CGContextFillRect(c, rect);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
@end
@kerembirinci
Copy link

Thank you so much. It helped me a lot.

@faithfracture
Copy link

Thanks for this!

Question: Why no call to UIGraphicsEndImageContext() before returning? I'm not real familiar with the way graphics context works, but according to the "Creating New Images" section of the apple docs (https://developer.apple.com/library/ios/documentation/2ddrawing/conceptual/drawingprintingios/HandlingImages/Images.html#//apple_ref/doc/uid/TP40010156-CH13-SW8) you're supposed to call that when you're done to pop the context you created off the graphics stack.

@joeboyscout04
Copy link

faithfracture is very wise. Leaving off the UIGraphicsEndImageContext() will cause a memory leak in your application. I know, because it happened to us after a developer used this code.

@VincentVToscano
Copy link

Great gist. Has anyone updated/forked the above based on the last 2 comments?

@fabiosoft
Copy link

If you have a UIImage instance instead of the name...

-(UIImage * _Nullable)tintMaskWithColor:(UIColor *_Nonnull)color{
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    CGContextRef c = UIGraphicsGetCurrentContext();
    [self drawInRect:rect];
    CGContextSetFillColorWithColor(c, [color CGColor]);
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
    CGContextFillRect(c, rect);
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment