---
title: "[Tech] How we do icon coloration at runtime #Objective-C #iOS"
description: "GoodBarber allows you to create full customized, beautiful apps, in just a few clicks. Among the hundreds of other features, we implemented an icon coloration p"
canonical_url: "https://www.goodbarber.com/blog/tech-how-we-do-icon-coloration-at-runtime-objective-c-ios-a88/"
lang: en
date: 2013-07-10
last_updated: 2017-06-14
---

# [Tech] How we do icon coloration at runtime #Objective-C #iOS

[Back](/blog/make-it-r13/)

# [Tech] How we do icon coloration at runtime #Objective-C #iOS

Written by [Dumè Siacci](https://www.goodbarber.com/blog/author/dominique-siacci/)  on Wednesday 10 July 2013

![](https://cmsphoto.ww-cdn.com/superstatic/41269/art/default/5221299-7791754.jpg?v=1437140853.990689)

GoodBarber allows you to create full customized, beautiful apps, in just a few clicks. Among the hundreds of other features, we implemented an icon coloration process, which you can use to create beautiful design effects.

We chose to let you choose amongst a large icon set — you can even upload your own TabBar icons — and you can imagine that it was completely impossible to anticipate all the customization possibilities. So we started to think about an automated customization process for these icons, and we wanted to keep a standard-based icon set (white PNGs with alpha channel only).

So here is what we developed to color the icons directly in the native client applications, with just a white PNG and a hexa color.

## Color an image with CGImageCreateWithMask

![](https://cmsphoto.ww-cdn.com/superstatic/41269/art/default/5221299-8386382.jpg?v=1437140854.270624)

The most pertinent function to color an image using a mask (our icon set) is CGImageCreateWithMask. This function takes a first parameter, the image to cut with the mask (the color), and a second parameter, the mask itself (the icon). Basically, the mask is a greyscale image, in which the white pixels are ignored and the black ones are kept, in alpha channel, according to their black intensity. So, we need to transform our original image to respect this specification.

We will follow two steps : create a negative image from our original image (white pixels need to become black), and add a white background.
We choosed to create an UIImage category.

## Create a negative image and replace the alpha with a white background

![](https://cmsphoto.ww-cdn.com/superstatic/41269/art/default/5221299-8386507.jpg?v=1437140854.410581)

`-(UIImage *) negativeImage

	{

	    UIGraphicsBeginImageContext(self.size);

	    CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);

	    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];

	    CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference);

	    CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor whiteColor].CGColor);

	    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, self.size.width, self.size.height));

	    UIImage *negativeImage = UIGraphicsGetImageFromCurrentImageContext();

	    UIGraphicsEndImageContext();

	    return negativeImage;

	}`

`- (UIImage *) imageWithWhiteBackground

	{

	    UIImage *negative = [self negativeImage];

	    UIGraphicsBeginImageContext(negative.size);

	    CGContextSetRGBFillColor (UIGraphicsGetCurrentContext(), 1, 1, 1, 1);

	    CGRect thumbnailRect = CGRectZero;

	    thumbnailRect.origin = CGPointZero;

	    thumbnailRect.size.width = negative.size.width;

	    thumbnailRect.size.height = negative.size.height;

	    CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, negative.size.height);

	    CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);

	    CGContextFillRect(UIGraphicsGetCurrentContext(), thumbnailRect);

	    CGContextDrawImage(UIGraphicsGetCurrentContext(), thumbnailRect, negative.CGImage);

	    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

	    UIGraphicsEndImageContext();

	    return newImage;

	}`

Once we've obtained a mask with the right specifications, we can apply on a plain color image (or a texture) using CGImageCreateWithMask.

## Apply a plain color image to the mask

![](https://cmsphoto.ww-cdn.com/superstatic/41269/art/default/5221299-8389834.jpg?v=1437140854.4924989)

+ (UIImage *) image:(UIImage *)image withMaskColor:(UIColor *)color
{
UIImage *formattedImage = [image imageWithWhiteBackground];

CGRect rect = {0, 0, formattedImage.size.width, formattedImage.size.height};
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
[color setFill];
UIRectFill(rect);
UIImage *tempColor = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGImageRef maskRef = [formattedImage CGImage];
CGImageRef maskcg = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);

CGImageRef maskedcg = CGImageCreateWithMask([tempColor CGImage], maskcg);
CGImageRelease(maskcg);
UIImage *result = [UIImage imageWithCGImage:maskedcg];
CGImageRelease(maskedcg);

return result;
}

We could easily imagine how to adapt this piece of code to apply a texture, as an image, instead of a plain color.

To optimize the process, it's useful to cache the UIImage object generated (on the file system, or memory), instead of making a call of this function each time the image is displayed.

## Useful links

- Apple Official Documentation : [Bitmap Images and Image Masks in the iOS documentation](https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html)

- [#Design](https://www.goodbarber.com/blog/tags/design)
- [#How To](https://www.goodbarber.com/blog/tags/how%20to)

![Dominique Siacci](https://blog.goodbarber.com/_public/profile/ca/ca3512f4dfa95a03169c5a670a4c91a19b3077b4-default.jpg)

About the author[Dominique Siacci](https://www.goodbarber.com/blog/author/dominique-siacci/)CTO

Co-founder and CTO of GoodBarber. I drive the product's technical vision: architecture, infrastructure, and more recently the integration of AI at the core of the platform. A developer at heart, I stay close to the code and the engineering decisions that enable thousands of GoodBarber users to publish their apps without writing a single line of code.

[Read more](https://www.goodbarber.com/blog/author/dominique-siacci/)

[![LinkedIn](https://portal.ww-cdn.com/portal_static/svg/base2021/linkedin.3ed8162e2a2b.svg)](https://fr.linkedin.com/in/dsiacci/)[![X](https://portal.ww-cdn.com/portal_static/svg/base2021/x.820492c586dd.svg)](https://twitter.com/dsiacci)[![Facebook](https://portal.ww-cdn.com/portal_static/svg/base2021/fb.be37c82b8283.svg)](https://www.facebook.com/dsiacci)
