iOS AVFoundation:将 CIFilter 应用于来自 AVCapturePhoto 的照片以进行保存的最佳方式

iOS AVFoundation: Best way to apply CIFilter to photos from AVCapturePhoto for saving

在我的 AVCapturePhotoCaptureDelegate 方法 public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) 中,我需要用滤镜效果保存照片,看来我需要 CIImage 才能使 CIFilter 工作。

我能做到:

let ciImage = CIImage(UIImage(photo.fileDataRepresentation())
// ...apply filter
let uiImage = UIImage(ciImage: filter.outputImage!)
let data = uiImage.jpegData(compressionQuality: 1.0)
// ...save data using PHAssetCreationRequest

但是涉及到一些图像和数据的转换,不知道有没有更好的方法呢?

谢谢!

是的,您可以在此处避免 UIImage 次转化。

首先,在某处创建一个 CIContext 并在每次过滤图像时重新使用它,因为创建一个图像的成本很高。这是为您执行实际图像过滤的对象(当您在使用 CIImage 初始化的 UIImage 上调用 jpegData 时,也会在后台发生这种情况)。默认参数 (let context = CIContext()) 应该可以正常工作。

然后在您的回调中,您可以执行以下操作:

let ciImage = CIImage(data: photo.fileDataRepresentation())
// apply filter...
let colorSpace = CGColorSpace(name: CGColorSpace.displayP3)! // or .sRGB, but you camera can most likely shoot P3
let outputData = self.ciContext.jpegRepresentation(of: filter.outputImage!, colorSpace: colorSpace, 
                                                   options: [kCGImageDestinationLossyCompressionQuality: 0.9])
// save data...

如果要另存为 HEIF,也可以使用 heifRepresentation。而且您显然也可以修改压缩质量。我只是将它添加到示例中,因为默认(1.0,即未压缩)会产生大文件。