The Three20 didn't help too much, but after several hours of hacking, I came up with a satisfactory solution to the problem. The two main tricks you need to know are:
- how to convert image to DeviceGray color space
- how to mask an image
Comments are embedded in the code:
+ (UIImage*) tabBarLikeIconWith:(UIImage*)tabBarIconImage
{
CGSize size = CGSizeMake(tabBarIconImage.size.width, tabBarIconImage.size.height);
CGRect bounds = CGRectMake(0, 0, tabBarIconImage.size.width, tabBarIconImage.size.height);
static UIImage* backgroundImage = nil;
if (backgroundImage == nil) {
backgroundImage = [UIImage imageNamed:@"TabBarLikeTransition.png"];
}
UIGraphicsBeginImageContext(size);
[backgroundImage drawAtPoint:CGPointMake(( size.width - backgroundImage.size.width) / 2, ( size.height - backgroundImage.size.height ) / 2)];
UIImage* workingBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(size);
[[UIColor whiteColor] set];
UIRectFill(bounds);
[tabBarIconImage drawAtPoint:CGPointMake(0, 0)];
UIImage* maskImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGColorSpaceRef grayscaleColorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
size.width,
size.height,
8,
8 * size.width,
grayscaleColorSpace,
0
);
CGContextDrawImage(bitmapContext, bounds, maskImage.CGImage);
CGImageRef maskImageRef = CGBitmapContextCreateImage(bitmapContext);
maskImage = [UIImage imageWithCGImage:maskImageRef];
CGContextRelease(bitmapContext);
CGImageRelease(maskImageRef);
CGColorSpaceRelease(grayscaleColorSpace);
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, true);
CGImageRef masked = CGImageCreateWithMask([workingBackgroundImage CGImage], mask);
CGImageRelease(mask);
return [UIImage imageWithCGImage:masked];
}
source
share