3

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: blendFilter.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

Kazi Nayeem
  • 373
  • 1
  • 6
Ric Santos
  • 13,489
  • 4
  • 35
  • 65

1 Answers1

2

You set backgroundImage of the blend filter to mask image which is not transparent. To get transparent background set backgroundImage to transparent color.

blendFilter.inputBackgroundImage = MTIImage.init(color: MTIColor.clear, sRGB: false, size: mtiImage.size)

MTIBlendWithMaskFilter's output image dimensions will be equal to the inputBackgroundImage's dimensions. Set the size as your need.

Kazi Nayeem
  • 373
  • 1
  • 6