Any idea why this image masking code does not work?

cocoa-touch, core-graphics, image-manipulation, iphone, uikit

Solution

This code may help you

- (UIImage*) maskImage:(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 masked = CGImageCreateWithMask([image CGImage], mask);
    return [UIImage imageWithCGImage:masked];

}

refer this example demonstration

Problem

I have this code to mask an image. Basically, I only work with PNG images. So I have a 300x400 PNG image with 24bits of color (PNG-24). I am not sure if it also has an alpha channel. But there's no transparency in it. Then, there is the image mask which is PNG-8bit without alpha channel. It is just black, grayscale and white. I create both images as UIImage. Both display correctly when putting them into an UIImageView. Then I create an UIImage out of them which contains the results of the masking operation, with this code: ``` + (UIImage*)maskImage:(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 masked = CGImageCreateWithMask([image CGImage], mask); return [UIImage imageWithCGImage:masked]; } ``` here's what I do with that: ``` UIImage *image = [UIImage imageNamed:@"coloredImagePNG24.png"]; UIImage *maskImage = [UIImage imageNamed:@"theMaskPNG8_Grayscale_NoAlpha.png"]; UIImage *maskedImage = [MyGraphicUtils maskImage:image withMask:maskImage]; UIImageView *testImageView = [[UIImageView alloc] initWithImage:maskedImage]; testImageView.backgroundColor = [UIColor clearColor]; testImageView.opaque = NO; ``` After all that, the coloredImagePNG24.png stays totally intact as it is. No masking is happening. But now the weird thing is: If I turn that around, i.e. use this image as the mask, and the mask as the color-image-to-mask, then I get something very ugly in grayscale (but masked ;) ). Any idea what's wrong with my code? UPDATE: I just googled for an different b/w png to use it as a mask. And then this one worked! But the one I made by myself does not work. So I assume that the code has big image decoding problems. I would have to "normalize" the images to a specific format, so that it works.

Original source