I have heavily borrowed (standard) code which applies a grayscale UIImage mask to a UIImage.
- (void) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
The above code gives a good idea of how to approach the problem(drawing over a context) but did not work for me. The code below works both on IOS 7 and previous versions(IOS 6.x).
+(UIImage*)maskImageExt:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef imageRef = image.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, true);
CGImageRef maskImageRef = CGImageCreateWithMask([image CGImage], mask);
CGContextRef context = CGBitmapContextCreate(nil,
CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef),
CGImageGetBitsPerComponent(imageRef),
CGImageGetBytesPerRow(imageRef),
CGImageGetColorSpace(imageRef),
CGImageGetBitmapInfo(imageRef));
CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
CGContextDrawImage(context, imageRect, maskImageRef);
CGImageRef maskedImageRef = CGBitmapContextCreateImage(context);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(mask);
CGContextRelease(context);
CGImageRelease(maskedImageRef);
return maskedImage;
}