I have an image which is a black ring:

black ring http://imageshack.us/a/img51/2029/blackcb.png

In my view, I need to display it as a white ring. So, to tint the image, I have written the below method:

- (UIImage *)getRingImage
    UIImage *ringImage = [UIImage imageNamed:@"ring"];

    CGFloat scale = [[UIScreen mainScreen] scale];

    UIGraphicsBeginImageContext(CGSizeMake(ringImage.size.width * scale, ringImage.size.height * scale));

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGRect rect = CGRectMake(0, 0, ringImage.size.width * scale, ringImage.size.height * scale);

    // Converting a UIImage to a CGImage flips the image,
    // so apply a upside-down translation
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -rect.size.height);

    // Set the fill color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextSetFillColorSpace(ctx, colorSpace);

    // Set the mask to only tint non-transparent pixels
    CGContextClipToMask(ctx, rect, ringImage.CGImage);

    // Set the fill color
    CGContextSetFillColorWithColor(ctx, [UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1].CGColor);

    UIRectFillUsingBlendMode(rect, kCGBlendModeColor);

    ringImage = UIGraphicsGetImageFromCurrentImageContext();


    return ringImage;

This code works fine. I want to know if there is a better way to do this.

  • \$\begingroup\$ What do you mean by "better?" \$\endgroup\$ – Robert Harvey May 14 '13 at 18:05
  • \$\begingroup\$ By "better" I mean, use of a different API which could achieve the same result but in less number of steps which in turn could lead to reduced execution time and CPU cycles. \$\endgroup\$ – Munish Poonia May 14 '13 at 18:14
  • 1
    \$\begingroup\$ I doubt it. Even when it took you 20 steps, the code is simple. If you are interested in other blend modes see robots.thoughtbot.com/post/46668544473/… \$\endgroup\$ – Jano May 14 '13 at 19:53

Try this function that I adapted. It creates a mono-color "mask" from an input image. If you use white, it turns every non-transparent pixel to white:

- (UIImage*)convertToMask: (UIImage *) image
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    CGRect imageRect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // Draw a white background (for white mask)
    CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
    CGContextFillRect(ctx, imageRect);

    // Apply the source image's alpha
    [image drawInRect:imageRect blendMode:kCGBlendModeDestinationIn alpha:1.0f];

    UIImage* outImage = UIGraphicsGetImageFromCurrentImageContext();


    return outImage;

Used like this:

self.imageView.image = [self convertToMask:self.imageView.image];
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.