UIImage masking problems iOS 7

I have heavily borrowed (standard) code which applies a grayscale UIImage mask to a UIImage.

- (void) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef imageRef = image.CGImage;  // main UIImage
    CGImageRef maskRef = maskImage.CGImage;  // grayscale UIImage mask

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                    CGImageGetHeight(maskRef),
                                    CGImageGetBitsPerComponent(maskRef),
                                    CGImageGetBitsPerPixel(maskRef),
                                    CGImageGetBytesPerRow(maskRef),
                                    CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask(imageRef, mask);

    maskedImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(mask);
    CGImageRelease(masked);

    imageView.image = maskedImage;

}

  • Access the JavaScriptCore engine of a UIWebView
  • how to set table cell height dynamically depending on text label length?
  • Could not load NIB in bundle: 'NSBundle when using storyboarding
  • UIDocumentPickerViewController - How to set the navigation bar color
  • Getting facebook public profile of a person in ios app
  • Best analytics offering for iPhone
  • I then save the imageView.image to a file. The code works like a charm in iOS 6 and 6.1; the saved image contains the main UIImage with the mask applied. However, I have noticed that this code does not perform in the same way in iOS 7 (iPhone). In iOS 7, the saved image contains only main UIImage without the mask applied. I am not sure whether the problem lies in the CGImageCreateWithMask() method or elsewhere.

    Any insight would be appreciated. Thank you so much in advance.

    3 Solutions Collect From Internet About “UIImage masking problems iOS 7”

    I found this issue on my app too and I solve it by following code.

    - (UIImage*)image:(UIImage*)image withMask:(UIImage*)maskImage
    {
        CGImageRef maskRef = maskImage.CGImage;
        CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);
    
        CGImageRef maskedImageRef = CGImageCreateWithMask([handledImage CGImage], mask);
        CGImageRelease(mask);
    
        // Under iOS 7, UIImage with mask no longer applied mask when saving it.
        // We draw the image to context and obtain image from context to get the image applied mask
        CGContextRef context = CGBitmapContextCreate(nil,
                                                     CGImageGetWidth(maskedImageRef),
                                                     CGImageGetHeight(maskedImageRef),
                                                     CGImageGetBitsPerComponent(maskedImageRef),
                                                     CGImageGetBytesPerRow(maskedImageRef),
                                                     CGImageGetColorSpace(maskedImageRef),
                                                     CGImageGetBitmapInfo(maskedImageRef));
    
        CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(maskedImageRef), CGImageGetHeight(maskedImageRef));
        CGContextDrawImage(context, imageRect, maskedImageRef);
        CGImageRef imageRef = CGBitmapContextCreateImage(context);
        UIImage *maskedImage = [UIImage imageWithCGImage:imageRef];
    
        CFRelease(imageRef);
        CGContextRelease(context);
        CGImageRelease(maskedImageRef);
    
        return maskedImage;
    }
    

    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;
    }
    

    Make sure that both images (the image to be masked and the mask itself) have an alpha channel! This solved the issue for me on iOS7.

    Then you should be able to use the old code you have used for iOS6.