使用 cgImage.mask 屏蔽两个 UIImages 无效,但适用于 imageview.layer.mask

mask two UIImages by using cgImage.mask not working, but works for imageview.layer.mask

我有两张图片,它们都有 Alpha 通道。我想把它们放在一起。它确实适用于 UIImageView,但我想通过使用 cgimage 来完成它,而无需创建 UIImageView。 我试过这样的 cgimage 不起作用:

    func  combine3(_ bg: UIImage, cover: UIImage) -> UIImage?{
        let size = CGSize(width: self.view.frame.width, height: self.view.frame.height)
        UIGraphicsBeginImageContext(size)
        
        let maskRef = cover.cgImage!
        let mask = CGImage.init(maskWidth: maskRef.width, height: maskRef.height, bitsPerComponent: maskRef.bitsPerComponent, bitsPerPixel: maskRef.bitsPerPixel, bytesPerRow: maskRef.bytesPerRow, provider: maskRef.dataProvider!, decode: nil, shouldInterpolate: false)
        let masked = bg.cgImage?.masking(mask!)
        let outPutImage = UIImage(cgImage: masked!)
        
        UIGraphicsEndImageContext()
        return outPutImage
    }

但是对于 UIImageView,效果很好:

        let bg = creatBGImageFinal()!
        bgIV.image = bg

        let cover = createCoverImageFinal(progress: 0)!
        let layer = CALayer()
        layer.contents = cover.cgImage
        layer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        maskIV.layer.mask = layer

背景资料: cover,就是中间有一个白色圆圈的图片,其他都是透明的: 结果:

首先,反转掩码:

cgImage 遮罩的规则是Dst = 1 - Src

然后使用不透明度将蒙版图像绘制到图像上下文中:

func combine3(_ bg: UIImage, cover: UIImage, size: CGSize) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(size, true, 1)
    defer {
        UIGraphicsEndImageContext()
    }
    let context = UIGraphicsGetCurrentContext()!
    let maskRef = cover.cgImage!
    let mask = CGImage.init(maskWidth: maskRef.width, height: maskRef.height, bitsPerComponent: maskRef.bitsPerComponent, bitsPerPixel: maskRef.bitsPerPixel, bytesPerRow: maskRef.bytesPerRow, provider: maskRef.dataProvider!, decode: nil, shouldInterpolate: false)!
    let masked = bg.cgImage!.masking(mask)!
    // adjust for lower-left-origin CG coordinates
    context.translateBy(x: 0, y: size.height)
    context.scaleBy(x: 1, y: -1)
    context.draw(masked, in: CGRect(origin: .zero, size: size))
    return UIGraphicsGetImageFromCurrentImageContext()
}

结果: