You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义CIColorCube滤镜无法修改UIImage问题求助

问题分析与解决方案

核心问题原因

  1. filter.setDefaults() 重置了滤镜参数
    调用该方法会将CIColorCube的所有参数恢复为系统默认值,默认的Cube是恒等变换(输入颜色直接输出),所以图像不会有任何修改。而你初始化时设置的自定义Cube数据会被完全覆盖。

  2. Cube维度不符合要求
    CIColorCube的inputCubeDimension必须是2的幂(如2、4、8、16、32),如果Constants.SHADES_COUNT不是这类数值,滤镜会无法正常工作,导致outputImage为nil。

  3. Cube数据生成逻辑冗余
    原代码前两层循环的变量未被使用,虽然对纯灰度图影响不大,但逻辑不够严谨,且未考虑非灰度图的兼容场景。


修正后的代码

1. 滤镜生成类(修正逻辑与参数检查)

class GreyToColoursFilterMaker {
    static let shared = GreyToColoursFilterMaker()
    let filter: CIFilter?
    
    private init() {
        let size = Constants.SHADES_COUNT
        // 强制检查维度是否为2的幂,否则初始化失败
        guard (size & (size - 1)) == 0, size >= 2 else {
            filter = nil
            return
        }
        
        var cubeRGB = [Float]()
        // 按B→G→R的顺序遍历所有颜色组合
        for b in 0 ..< size {
            let blue = CGFloat(b) / CGFloat(size - 1)
            for g in 0 ..< size {
                let green = CGFloat(g) / CGFloat(size - 1)
                for r in 0 ..< size {
                    let red = CGFloat(r) / CGFloat(size - 1)
                    // 计算灰度值(兼容灰度图与非灰度图)
                    let gray = (red + green + blue) / 3.0
                    // 按原需求生成色相:从240°(蓝色)过渡到0°(红色)
                    let hue = (1 - gray) * 240 / 360
                    let destColor = UIColor(hue: hue, saturation: 1, brightness: 1, alpha: 1)
                    
                    let colorParts = destColor.rgba
                    cubeRGB.append(Float(colorParts.red))
                    cubeRGB.append(Float(colorParts.green))
                    cubeRGB.append(Float(colorParts.blue))
                    cubeRGB.append(Float(colorParts.alpha))
                }
            }
        }
        
        // 正确生成Cube数据
        let data = Data(buffer: UnsafeBufferPointer(start: cubeRGB, count: cubeRGB.count))
        filter = CIFilter(name: "CIColorCube", parameters: [
            kCIInputCubeDimensionKey: size,
            kCIInputCubeDataKey: data
        ])
    }
}

2. 滤镜使用代码(移除setDefaults)

if let filter = GreyToColoursFilterMaker.shared.filter {
    guard let ciImg = CIImage(image: img) else {
        return
    }
    filter.setValue(ciImg, forKey: kCIInputImageKey)
    if let filteredImageData = filter.outputImage {
        // 可选:启用硬件加速提升性能
        let ciContext = CIContext(options: [.useSoftwareRenderer: false])
        if let filteredImageRef = ciContext.createCGImage(filteredImageData, from: filteredImageData.extent) {
            img = UIImage(cgImage: filteredImageRef)
        }
    }
}

关键说明

  • 确保Constants.SHADES_COUNT设置为2的幂(比如16或32),否则滤镜会初始化失败。
  • 移除filter.setDefaults(),避免自定义Cube参数被重置。
  • 优化后的Cube生成逻辑兼容非灰度图,同时保持原需求的灰度级转色相效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:52:54