Sjakelien
Sjakelien

Reputation: 2317

iOS: How to add an Alpha Channel to a native iPhone Picture

I'm trying to mask a picture taken with my iphone. Here I found a way how to do that. However, the image-to-be-masked apparently needs an alpha channel, and pictures from the iPhone don't have that. So, I found this topic discussing how to add such a channel. Unfortunately, that code doesn't work for me (Xcode 6, iOS 7/8)

Does any of you know how to accomplish this?

Thanks in advance

Upvotes: 1

Views: 1672

Answers (2)

Sjakelien
Sjakelien

Reputation: 2317

OK, I have the honour to answer my own question, just because my question itself was ill-formulated, and built upon assumptions, that likely were not clear to anyone. I hope though, that someone with the same poor logic as me will end up at this page, and find this all very useful.

Let me first explain what went wrong:

  1. I assumed that the -

    (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage

    that I ran into would affect the image, but in fact it affects the DISPLAY of that image in an UIImageView.

  2. In my debug chain, I saved the masked image to a file, just to end up with a file without a mask.
  3. Google's results suggested that I needed first to add an alpha channel to the image, before I could apply an alpha at all.

So I got lost several times, dragging you into this.

Being stuck with that unmasked image, I sent out another query to Google, ending up with the following:

http://iphonedevsdk.com/forum/iphone-sdk-development/96918-round-corners-on-uiimage-not-uiimageview.html

This actually answered my question. The

-(UIImage *)makeRoundedImage:(UIImage *) image radius: (float) radius;

method returns a destructed image with an alpha mask. Since I needed a perfect circle, I could just get rid of the radius parameter.

Thank you for all your thinking and patience. I dearly apologise for the inconvenience.

Upvotes: 0

Brian Shamblen
Brian Shamblen

Reputation: 4703

I tried the code from the first link:

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

}

Initially it didn't work, because the mask image that I used was partially transparent. I recreated the mask image making sure than the entire image was either black or white and it worked.

I found the following information on another website, which led me to this conclusion:

NOTE: The mask image cannot have ANY transparency. Instead, transparent areas must be white or some value between black and white. The more towards black a pixel is the less transparent it becomes.

In case it's related to the code that you're using to load the image from the image picker, here's the code that I used to load the image and the mask:

-(IBAction)selectImageFromCameraRoll:(UIButton *)sender
{
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
    {
        NSArray *media = [UIImagePickerController
                          availableMediaTypesForSourceType: UIImagePickerControllerSourceTypePhotoLibrary];

        if ([media containsObject:(NSString*)kUTTypeImage] == YES) {
            UIImagePickerController *picker = [[UIImagePickerController alloc] init];
            picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            [picker setMediaTypes:[NSArray arrayWithObject:(NSString *)kUTTypeImage]];

            picker.delegate = self;

            [self presentViewController:picker animated:YES completion:nil];
        }
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Oops!"
                                                        message:@"This device does not have a photo library."
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType];

    if([mediaType isEqualToString:(NSString*)kUTTypeImage])
    {
        UIImage *photoTaken = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        self.imageView.image = [self maskImage:photoTaken withMask:[UIImage imageNamed:@"mask.png"]];
    }

    [picker dismissViewControllerAnimated:NO completion:nil];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [picker dismissViewControllerAnimated:YES completion:nil];
}

Here's a link to the mask image that I used:

mask.png Download and rename the file.

Upvotes: 1

Related Questions