core-graphicsappkitnsbitmapimagerep

NSGraphics/CoreGraphics Grayscale to alpha


I have two NSBitmapImageReps, one containing the main image and one containing a grayscale mask for the image (where black is opaque and white is transparent). Is there a way to combine the two to create a single image with alpha transparency? I know I could iterate the bitmap data and set the alpha for each individual pixel, but I'm wondering if there's another way to convert the grayscale to alpha. I'm happy to use CoreGraphics if necessary.

[edit] The mask may not strictly be grayscale.


Solution

  • I found the answer lies in CoreImage. First use colorInvert to invert the mask, then combine it with the main image using blendWithMask:

    func maskImage(_ image: NSBitmapImageRep, _ mask: NSBitmapImageRep) -> NSBitmapImageRep? {
        if let ciMask = CIImage(bitmapImageRep: mask) {
            let invert = CIFilter.colorInvert()
            invert.inputImage = ciMask
            if let invMask = invert.outputImage, let input = CIImage(bitmapImageRep: image) {
                let blend = CIFilter.blendWithMask()
                blend.inputImage = input
                blend.maskImage = invMask
                if let output = blend.outputImage {
                    return NSBitmapImageRep(ciImage: output)
                }
            }
        }
        return nil
    }