2
\$\begingroup\$

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();

    CGColorSpaceRelease(colorSpace);
    UIGraphicsEndImageContext();

    return ringImage;
}

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

\$\endgroup\$
3
  • \$\begingroup\$ What do you mean by "better?" \$\endgroup\$ May 14, 2013 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\$ May 14, 2013 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, 2013 at 19:53

1 Answer 1

2
\$\begingroup\$

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();

    UIGraphicsEndImageContext();

    return outImage;
}

Used like this:

self.imageView.image = [self convertToMask:self.imageView.image];
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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