Enhance RAW image processing with Core Image
Graphics, Games & Media 高级 16m

使用 Core Image 增强 RAW 图像处理

Enhance RAW image processing with Core Image

2026年6月10日

在 Apple 官方观看视频

一句话判断

这场 Session 最值得关注的一件事是:Apple 终于把 Core ML 模型塞进了 RAW 解码管线(Pipeline),用神经网络接管了去马赛克(Demosaic)和降噪(Denoise),这意味着第三方修图 App 终于能拿到和系统相册一样“作弊”级别的 RAW 解析画质了。

这场 Session 讲了什么

过去我们在 iOS 上做 RAW 处理,CIRAWFilter 的底层算法虽然够用,但在高 ISO 噪点和复杂纹理(比如刺绣、细小文字)上,总是差系统相册一截。这次 Apple 直接掏出了 RAW 9 版本,底层换成了基于 Apple Neural Engine (ANE) 的 Core ML 模型。这不仅是算法升级,更是算力调度的转变。

对开发者来说,最直观的变化是 CIRAWFilter 的 API 做了减法。因为 ML 模型把色彩降噪、摩尔纹这些脏活累活全包了,像 colorNoiseReductionAmount 这种手动参数直接废弃。你只需要把 decoderVersion 切到 version9,就能白嫖 784 款相机的顶级解析力。

影响最大的是那些做专业摄影、扫描或医学影像 App 的团队。以前为了画质,大家可能得自己手搓 Metal shader 或者接第三方 SDK,现在只要搞定 CIContext 的内存和缓存策略,就能在应用内实现丝滑的 RAW 编辑和极速导出。

值得深挖的点

RAW 9 的“黑盒化”与参数取舍

Apple 这次在 RAW 9 上做了一个非常激进的决定:干掉开发者的部分控制权。colorNoiseReductionAmountdetailAmountmoireReductionAmount 在 RAW 9 中直接失效。为什么这么干?因为传统的 RAW 管线是各个模块串联的,降噪和锐化互相打架,开发者调参往往是在做妥协。而 RAW 9 用一个端到端的 Core ML 模型同时处理去马赛克和降噪,模型自己学到了最优解,手动干预反而会破坏 ML 的特征提取。

这种 trade-off 很 Apple:给你 90 分的傻瓜式极致画质,但剥夺了你调到 95 分(或者搞砸成 50 分)的自由。对于追求极致自定义的硬核修图 App(比如想保留特定胶片颗粒感的),这可能有点难受,只能回退到 RAW 8。但对于 95% 的应用场景,直接用 ANE 跑出干净、锐利的画面,省下几百行调参 UI 代码,绝对是稳赚不赔的买卖。

CIContext 调优:交互式编辑与批量导出的冰火两重天

Session 里最值钱的其实是性能调优部分。RAW 9 跑 ML 模型极其吃资源,如果直接无脑渲染,App 分分钟 OOM (Out of Memory) 或者卡成 PPT。Apple 明确把场景分成了两派。

做交互式编辑(用户拖拽曝光滑块),重点是“快”和“省”。必须用 scaleFactor 降采样,开启 cacheIntermediates 让 Core Image 缓存中间结果,并且一定要申请 Extended Virtual Addressing entitlement 来突破内存限制,最后直接渲染到 Metal-backed 的 MTKView

做批量导出(后台转码 100 张 RAW),重点是“吞吐量”。这时候缓存中间结果就是浪费内存,必须把 cacheIntermediates 关掉,同时把 memoryLimit 从默认的 256MB 拉高到 512MB 甚至 1024MB,让 Core Image 放开手脚去申请内存做全分辨率计算。搞混这两个场景的配置,你的 App 要么卡死,要么闪退。

代码片段

1. 启用 RAW 9 并配置交互式编辑

场景:用户在 UI 上拖动滑块实时预览 RAW 照片。

// 检查并启用 RAW 9
let rawFilter = CIRAWFilter(imageURL: rawURL)!
if rawFilter.supportedDecoderVersions.contains(.version9) {
    rawFilter.decoderVersion = .version9
}

// 配置交互式编辑的 CIContext
let interactiveCtx = CIContext(options: [
    .cacheIntermediates: true, // 开启缓存,避免拖动滑块时重复跑 ML 模型
    .workingColorSpace: CGColorSpace(name: CGColorSpace.extendedLinearSRGB)!
])

// 坑:别忘了在 entitlements 里开启 Extended Virtual Addressing,否则大图缓存必崩。

2. 批量导出 RAW 到 HEIF

场景:后台将多张 RAW 照片全分辨率导出为 HEIF。

// 配置批量导出的 CIContext
let exportCtx = CIContext(options: [
    .cacheIntermediates: false, // 关闭缓存,导出是一次性的,缓存只会撑爆内存
    .memoryLimit: 1024 * 1024 * 1024 // 放宽内存限制到 1GB,提升全分辨率渲染速度
])

// 坑:iOS 默认 memoryLimit 只有 256MB,处理高像素 RAW (如 4500万像素) 时极易触发 Jetsam 闪退。

3. CIImageProcessor 使用临时缓冲区

场景:在自定义 CIImageProcessorKernel 中需要额外的内存做中间计算。

class MyProcessor: CIImageProcessorKernel {
    override class func process(with inputs: [CIImageProcessorInput]?,
                                arguments: [String: Any]?,
                                output: CIImageProcessorOutput) throws {
        guard let input = inputs?.first,
              let srcBuffer = input.pixelBuffer,
              let dstBuffer = output.pixelBuffer else { return }
        
        // 从 Core Image 的缓存池借一个临时 PixelBuffer
        guard let scratchBuffer = output.temporaryPixelBuffer(
            identifier: "myScratch", 
            format: srcBuffer.format
        ) else { return }
        
        // 使用 scratchBuffer 进行复杂的中间计算...
        // 坑:temporaryPixelBuffer 是由 Core Image 管理的,千万不要在 process 方法外持有或异步访问它。
    }
}

最佳实践

已有项目的迁移策略 不要全局一刀切替换 RAW 9。建议在 App 的设置里加个“使用增强版 RAW 引擎”的开关,或者根据设备芯片(如 A15/M1 及以上)自动判断。老设备跑 RAW 9 的 ML 模型可能会导致发热和耗电剧增,保留 RAW 8 作为 fallback 是明智之举。同时,检查你现有的 UI,把 colorNoiseReductionAmount 等失效的滑块隐藏掉,避免用户拖动了却没反应。

新项目的采用建议 如果你在做类似 Lightroom 的竞品,直接拥抱 RAW 9 和 MTKView。把 UI 交互和渲染管线彻底解耦,UI 线程只负责改 CIRAWFilter 的属性,渲染全部丢给 Metal 管线。利用 supportedCameraModels(for: .version9) 接口,在用户导入照片时,如果相机型号不支持 RAW 9,提前给用户提示或无缝降级。

实战中容易踩的坑 最大的坑是 CIContext 的复用。很多开发者喜欢全局单例一个 CIContext,这在 RAW 9 时代是致命的。交互式预览和后台导出对内存和缓存的需求完全相反,必须为这两个场景分别实例化独立的 CIContext

还有什么值得关注

  • CIImageProcessor 支持显式指定 Output Tile Sizes:写自定义 Metal 滤镜时,终于能精确控制图块大小了,这对优化 GPU 缓存命中率(Cache hit rate)极其有用。
  • Extended Virtual Addressing entitlement:在 iPad 和 Mac 上处理超大 RAW 拼图时,加上这个 entitlement 能直接突破 4GB 内存寻址限制,属于“加了就变神”的隐藏开关。
  • 原生支持 DNG:RAW 9 对原生拍摄 DNG 格式的设备(比如 iPhone 的 ProRAW 或某些 Leica)支持得最好,不需要等 Apple 推送特定的相机配置文件。
CoreImage RAW CoreML CIImageProcessor Metal