2

I have a UIImage (generated by a user drawing) that has a white background. I'd like to make the white portions of this image transparent. I'd also like to save this to a PNG file.

I've looked around on forums but can't figure out how to mask the image correctly. Has anyone tried this before?

Thanks.

jmoney
  • 133
  • 4
  • 11

4 Answers4

3

Try something like this...

CGImageRef myMaskedImage = [myImage CGImage];
const float whiteMask[6] = { 255,255,255, 255,255,255 };
CGImageRef myColorMaskedImage = CGImageCreateWithMaskingColors(image, whiteMask);

CGDataProviderRef provider;
CGImageRef myPngImage = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt: 72], kCGImagePropertyDPIHeight, [NSNumber numberWithInt: 72], kCGImagePropertyDPIWidth, nil];
CGImageDestinationRef destRef = CGImageDestinationCreateWithURL ((CFURLRef)outPath, (CFStringRef)@"image.png" , 1, NULL);
CGImageDestinationAddImage(destRef, myPngImage, (CFDictionaryRef)options);
CGImageDestinationFinalize(destRef);
CGRelease(destRef);

CGImageRelease(myColorMaskedImage);
CGImageRelease(myPngImage);

from the rather long winded Quartz2d Programming Guide and this mailing list message.

slf
  • 22,595
  • 11
  • 77
  • 101
1

You can try this

extension UIImage {
    func imageByMakingWhiteBackgroundTransparent() -> UIImage? {

        let image = UIImage(data: self.jpegData(compressionQuality: 1.0)!)!
        let rawImageRef: CGImage = image.cgImage!

        let colorMasking: [CGFloat] = [222, 255, 222, 255, 222, 255]
        UIGraphicsBeginImageContext(image.size);

        let maskedImageRef = rawImageRef.copy(maskingColorComponents: colorMasking)
        UIGraphicsGetCurrentContext()?.translateBy(x: 0.0,y: image.size.height)
        UIGraphicsGetCurrentContext()?.scaleBy(x: 1.0, y: -1.0)
        UIGraphicsGetCurrentContext()?.draw(maskedImageRef!, in: CGRect.init(x: 0, y: 0, width: image.size.width, height: image.size.height))
        let result = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return result

    }

}
Jagveer Singh
  • 2,258
  • 19
  • 34
  • Why do you convert to jpeg first and then load it as such again? Is there a reason for it? Just want to understand what's going on here. The solution as such is working! – Georg Sep 02 '22 at 07:20
  • sorry bro, dont have more details now, answer i wrote is 2 years back – Jagveer Singh Sep 02 '22 at 07:33
0

You could try making the starting UIImage completely transparent and then have another UIImageView behind it that is completely white.

Tozar
  • 976
  • 9
  • 20
0

You're going to have to get at the raw data, look for white pixels, modify the alpha of those pixels and save to a new NSData object and then convert that to a PNG.

It's not difficult, but I wouldn't call it trivial.

amattn
  • 10,045
  • 1
  • 36
  • 33