You need to enable JavaScript to run this app. 如何正确添加图片遮罩?Swift添加图片光效时遮罩仅显白色如何解决
优惠活动
大模型
产品
解决方案
定价
更多

如何正确添加图片遮罩?Swift添加图片光效时遮罩仅显白色如何解决

问题原因

遮罩区域显示为白色主要由两点导致:

  • CGImage初始化遮罩对输入的遮罩图片有严格格式要求,必须为无alpha通道的灰度图,普通彩色、带alpha通道的图片直接传入会导致遮罩计算异常,出现全白显示
  • 直接对原图做遮罩时,遮罩后透明的区域会显示底层视图的白色背景,不符合添加光效的需求逻辑

解决步骤

1. 预处理遮罩图片为符合要求的灰度图

添加灰度转换方法,将输入的遮罩图转换为符合CGImage要求的格式:

func convertToGrayscaleMask(image: UIImage) -> UIImage? {
    let size = image.size
    let graySpace = CGColorSpaceCreateDeviceGray()
    guard let context = CGContext(data: nil,
                                  width: Int(size.width),
                                  height: Int(size.height),
                                  bitsPerComponent: 8,
                                  bytesPerRow: 0,
                                  space: graySpace,
                                  bitmapInfo: CGImageAlphaInfo.none.rawValue) else {
        return nil
    }
    context.draw(image.cgImage!, in: CGRect(origin: .zero, size: size))
    guard let grayCGImage = context.makeImage() else {
        return nil
    }
    return UIImage(cgImage: grayCGImage, scale: image.scale, orientation: image.imageOrientation)
}

灰度遮罩的生效规则为:黑色区域对应上层素材完全保留,白色区域对应上层素材完全透明,中间灰度值对应半透明效果。

2. 修正原遮罩方法

原方法未处理UIImage的scale和方向属性,易出现遮罩错位、变形问题,修正后代码:

func maskImage(image: UIImage, mask: UIImage) -> UIImage? {
    guard let grayMask = convertToGrayscaleMask(image: mask),
          let maskCGImage = grayMask.cgImage,
          let sourceCGImage = image.cgImage else {
        return nil
    }
    guard let imageMask = CGImage(maskWidth: maskCGImage.width,
                                  height: maskCGImage.height,
                                  bitsPerComponent: maskCGImage.bitsPerComponent,
                                  bitsPerPixel: maskCGImage.bitsPerPixel,
                                  bytesPerRow: maskCGImage.bytesPerRow,
                                  provider: maskCGImage.dataProvider!,
                                  decode: nil,
                                  shouldInterpolate: true) else {
        return nil
    }
    guard let maskedCGImage = sourceCGImage.masking(imageMask) else {
        return nil
    }
    return UIImage(cgImage: maskedCGImage, scale: image.scale, orientation: image.imageOrientation)
}

3. 调整光效实现逻辑

如果你的需求是在指定区域添加光效,不要直接对原图做遮罩,按以下步骤实现:

  • 准备好光效素材图(光晕、亮光类素材)
  • 用你需要显示光效的区域作为遮罩,对光效素材图执行遮罩处理
  • 将处理后的光效图叠加在原图上方,根据需要调整透明度和图层混合模式,即可得到自然的光效效果

内容的提问来源于stack exchange,提问作者Kamlesh Shingarakhiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 18:54:03