Question

I know that there are already 2 relevant posts on that, but it's not clear...

So the case is this...:

I have a UIImage which consists of a png file requested from a url on the net. Is it possible to mask out the white color so it becomes transparent?

Everything I have tried so far with CGImageCreateWithMaskingColors, returns a white image...

Any help guys would be precious :)

Was it helpful?

Solution

Ok since I found a solution and it's working fine, I am answering my question and I really believe that this will be useful to many people having the same need.

First of all I thought that would be nice to extend my UIImages via a category:

UIImage+Utils.h

#import <UIKit/UIKit.h>

@interface UIImage (Utils)

- (UIImage*)imageByClearingWhitePixels;
@end

UIImage+Utils.m

#import "UIImage+Utils.h"

@implementation UIImage (Utils)

#pragma mark Private Methods
- (CGImageRef) CopyImageAndAddAlphaChannel:(CGImageRef) sourceImage {
    CGImageRef retVal = NULL;

    size_t width = CGImageGetWidth(sourceImage);
    size_t height = CGImageGetHeight(sourceImage);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef offscreenContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedFirst);

    if (offscreenContext != NULL) {
        CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), sourceImage);

        retVal = CGBitmapContextCreateImage(offscreenContext);
        CGContextRelease(offscreenContext);
    }

    CGColorSpaceRelease(colorSpace);

    return retVal;
}

- (UIImage *) getMaskedArtworkFromPicture:(UIImage *)image withMask:(UIImage *)mask{

    UIImage *maskedImage;
    CGImageRef imageRef = [self CopyImageAndAddAlphaChannel:image.CGImage];
    CGImageRef maskRef = mask.CGImage;
    CGImageRef maskToApply = CGImageMaskCreate(CGImageGetWidth(maskRef),CGImageGetHeight(maskRef),CGImageGetBitsPerComponent(maskRef),CGImageGetBitsPerPixel(maskRef),CGImageGetBytesPerRow(maskRef),CGImageGetDataProvider(maskRef), NULL, NO);
    CGImageRef masked = CGImageCreateWithMask(imageRef, maskToApply);
    maskedImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(imageRef);
    CGImageRelease(maskToApply);
    CGImageRelease(masked);
    return maskedImage;

}

#pragma mark Public Methods
- (UIImage*)imageByClearingWhitePixels{

    //Copy image bitmaps
    float originalWidth = self.size.width;
    float originalHeight = self.size.height;
    CGSize newSize;

    newSize = CGSizeMake(originalWidth, originalHeight);

    UIGraphicsBeginImageContext( newSize );

    [self drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    //Clear white color by masking with self
    newImage = [self getMaskedArtworkFromPicture:newImage withMask:newImage];

    return newImage;
}

@end

Finally, I am able to use it like this: (After I have imported UIImage+Utils.h of course)

UIImage *myImage = [...]; //A local png file or a file from a url
UIImage *myWhitelessImage = [myImage imageByClearingWhitePixels]; // Hooray!

OTHER TIPS

It is not really possible, at least no easy way, certainly no API call. It is basically an image editing problem usually done with Photoshop. Most images that have a transparent background were created that way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top