Monday 26 October 2020

How to mask an image with MetalPetal and output with transparency

I have an opaque image, and an opaque mask image. Using MetalPetal and it's MTIBlendWithMaskFilter I can create an output image, which correctly masks the input image, but is opaque with a black background.

I would like the output image to have an alpha channel, eg instead of black pixels have transparent pixels.

func mt_blend(image: UIImage, with mask: UIImage) -> UIImage {
    let ciMaskImage = CIImage(cgImage: mask.cgImage!)
    let mtiMaskImage = MTIImage(ciImage: ciMaskImage, isOpaque: true)
    let mtiMask = MTIMask(content: mtiMaskImage)
    
    let ciImage = CIImage(cgImage: image.cgImage!)
    let mtiImage = MTIImage(ciImage: ciImage, isOpaque: true)

    let contextOptions = MTIContextOptions()
    let context = try! MTIContext(device: MTLCreateSystemDefaultDevice()!, options: contextOptions)

    let blendFilter = MTIBlendWithMaskFilter()
    blendFilter.inputMask = mtiMask
    blendFilter.inputBackgroundImage = mtiMaskImage
    blendFilter.inputImage = mtiImage
    
    let outputImage = try! context.makeCGImage(from: opacityFilter.outputImage!)
    return UIImage(cgImage: outputImage)
}

It would appear my misunderstanding or misuse of premultiplyingAlpha is the problem here.

Input image:

enter image description here

Mask image:

enter image description here

Output image:

enter image description here



from How to mask an image with MetalPetal and output with transparency

No comments:

Post a Comment