Highlight
iOS 17 为 AVCapturePhotoOutput 引入了延迟照片处理、零快门延迟和响应式拍摄三大 API,让相机应用在保持 Deep Fusion 最高画质的同时,实现更快的连拍速度和更短的快门延迟。
核心内容
拍照时最扫兴的事,莫过于按下快门后等待处理完成才能拍下一张。Deep Fusion 带来的细节提升有目共睹,羽毛纹理、胡须细节都清晰锐利。但这个处理过程是同步的,必须完成后才能开始下一次拍摄。
(01:43)在 iOS 17 之前,开发者只能在画质和速度之间做取舍。选择 quality 优先级获得最佳画质, shot-to-shot 时间就会变长。选择 balanced 或 speed 则牺牲画质换取速度。
Apple 今年给出的方案是:把处理推迟到相机会话结束后进行。
延迟照片处理
(01:43)延迟照片处理(Deferred Photo Processing)的核心思路是:拍摄时先返回一个轻量级的代理照片(proxy photo),让用户可以继续拍摄;真正的 Deep Fusion 处理在后台完成,等用户退出相机应用后再执行。
这个代理照片被存入照片库作为占位符。当用户之后查看或分享时,系统要么按需完成处理,要么在设备空闲时在后台自动完成。
零快门延迟
(16:03)另一个常见痛点是快门延迟。你按下快门时取景框里是一个画面,拍出来的却是之后的画面。在 30fps 下每帧只显示 33 毫秒,但这就足以错过最佳瞬间。
零快门延迟(Zero Shutter Lag)利用环形缓冲区保存过去的帧数据。按下快门时,相机会”回溯时间”,从缓冲区中提取按下快门那一刻的帧来合成照片。
响应式拍摄
(19:44)响应式拍摄(Responsive Capture)允许拍摄阶段和处理阶段重叠。当第一张照片还在处理时,第二张照片的拍摄请求就可以开始执行。这大幅提升了连拍速度。
配合快速拍摄优先级(Fast Capture Prioritization),当检测到用户快速连拍时,系统会自动将画质从最高降至平衡档,保持稳定的 shot-to-shot 时间。
视频特效与手势反应
(27:07)macOS Sonoma 将视频特效从控制中心移到了独立菜单。Portrait 和 Studio Light 效果现在可以调节强度。新增的反应特效(Reactions)支持手势触发:竖拇指、倒拇指、爱心、胜利手势等,会在视频上渲染气球、烟花、激光等动画效果。
详细内容
启用延迟照片处理
(05:46)在配置 AVCapturePhotoOutput 时,检查并启用延迟处理:
// 检查是否支持延迟照片处理
if photoOutput.isAutoDeferredPhotoDeliverySupported {
photoOutput.isAutoDeferredPhotoDeliveryEnabled = true
}
关键点:
isAutoDeferredPhotoDeliverySupported检查当前设备是否支持isAutoDeferredPhotoDeliveryEnabled开启后,相机会自动判断哪些照片适合延迟处理- 不需要逐张设置,系统会自动处理
保存代理照片到照片库
(07:42)拍摄完成后,使用新的代理回调保存照片:
func photoOutput(_ output: AVCapturePhotoOutput,
didFinishCapturingDeferredPhotoProxy deferredPhotoProxy: AVCaptureDeferredPhotoProxy?,
error: Error?) {
guard error == nil, let proxy = deferredPhotoProxy else { return }
PHPhotoLibrary.shared().performChanges {
let request = PHAssetCreationRequest.forAsset()
request.addResource(with: .photoProxy,
data: proxy.fileDataRepresentation()!,
options: nil)
} completionHandler: { success, error in
// 处理完成回调
}
}
关键点:
- 使用
didFinishCapturingDeferredPhotoProxy回调接收代理照片 PHAssetResourceType.photoProxy告诉 PhotoKit 这是需要延迟处理的照片- 必须尽快将代理数据存入照片库,避免应用被挂起后数据丢失
请求处理中的照片
(09:43)当用户查看正在处理中的照片时,可以启用二次降级图像:
let options = PHImageRequestOptions()
options.allowSecondaryDegradedImage = true
PHImageManager.default().requestImage(for: asset,
targetSize: targetSize,
contentMode: .aspectFit,
options: options) { image, info in
if let info = info {
if info[PHImageResultIsDegradedKey] as? Bool == true {
// 显示中间质量的图像
} else {
// 显示最终图像
}
}
}
关键点:
allowSecondaryDegradedImage会在低质量占位图和最终图之间提供一个中等质量的图像- 两个降级图像都会标记
PHImageResultIsDegradedKey - 最终图像不会有这个标记
零快门延迟
(18:24)零快门延迟在 iOS 17 上默认启用,链接 iOS 17 SDK 的应用自动获得支持。如需关闭:
// 检查支持情况
if photoOutput.isZeroShutterLagSupported {
photoOutput.isZeroShutterLagEnabled = false // 默认 true
}
关键点:
- 仅当
isHighestPhotoQualitySupported为 true 的 preset/format 上支持 - 闪光灯、手动曝光、包围曝光、多摄像头同步拍摄不支持零快门延迟
- 从点击事件到调用
capturePhoto之间的延迟要尽量短
响应式拍摄与就绪协调器
(21:31)启用响应式拍摄:
// 必须先启用零快门延迟
if photoOutput.isResponsiveCaptureSupported {
photoOutput.isResponsiveCaptureEnabled = true
}
// 快速拍摄优先级
if photoOutput.isFastCapturePrioritizationSupported {
photoOutput.isFastCapturePrioritizationEnabled = true
}
使用就绪协调器管理快门按钮状态:
let readinessCoordinator = AVCapturePhotoOutputReadinessCoordinator(photoOutput: photoOutput)
readinessCoordinator.delegate = self
// 拍摄前告知协调器
readinessCoordinator.startTrackingCaptureRequest(using: photoSettings)
photoOutput.capturePhoto(with: photoSettings, delegate: self)
// 实现委托方法
func readinessCoordinator(_ coordinator: AVCapturePhotoOutputReadinessCoordinator,
captureReadinessDidChange captureReadiness: AVCapturePhotoOutput.CaptureReadiness) {
switch captureReadiness {
case .ready:
shutterButton.isEnabled = true
case .notReadyMomentarily:
shutterButton.isEnabled = false
case .notReadyWaitingForCapture:
shutterButton.isEnabled = false // 闪光灯充电中
case .notReadyWaitingForProcessing:
shutterButton.isEnabled = false // 处理中
default:
break
}
}
关键点:
AVCapturePhotoOutputReadinessCoordinator监听拍摄就绪状态变化.notReadyWaitingForCapture表示还在等待从传感器获取帧(如闪光灯场景).notReadyWaitingForProcessing表示正在处理中- 即使不使用响应式拍摄,也可以使用就绪协调器
视频反应特效
(29:59)在 iOS 上,应用需要通过 Info.plist 声明支持反应特效:
<key>NSCameraReactionEffectsEnabled</key>
<true/>
或者声明 VoIP 后台模式:
<key>UIBackgroundModes</key>
<array>
<string>voip</string>
</array>
触发反应特效:
// 检查设备是否支持反应特效
if device.activeFormat.reactionEffectsSupported {
// 触发特效
device.performEffect(for: .thumbsUp)
}
// 获取系统图标
let imageName = AVCaptureReactionType.thumbsUp.systemImageName
let image = UIImage(systemName: imageName)
// 监听特效进行中状态
// reactionEffectsInProgress 返回 AVCaptureReactionEffectStatus 数组
关键点:
AVCaptureReactionType包含 thumbsUp、thumbsDown、balloons、heart、fireworks、rain、confetti、laserssystemImageName提供对应的系统图标- 手势触发的特效位置可能与程序触发不同
- 特效进行时帧率可能从 60fps 降至 30fps
核心启发
1. 为相机应用添加”专业连拍模式”
做什么:在相机应用中实现一个高速连拍模式,利用响应式拍摄 API 实现每秒 4-5 张的连拍速度。
为什么值得做:传统相机应用受限于 Deep Fusion 处理时间,连拍速度受限。响应式拍摄让处理阶段和拍摄阶段重叠,用户不再错过动作瞬间。
怎么开始:启用 isResponsiveCaptureEnabled 和 isFastCapturePrioritizationEnabled,使用 AVCapturePhotoOutputReadinessCoordinator 管理快门按钮状态,给用户提供清晰的拍摄反馈。
2. 构建一个”零等待”相机应用
做什么:结合延迟照片处理和零快门延迟,打造一个按下快门立刻就能拍下一张的相机应用。
为什么值得做:Deep Fusion 的画质和快速连拍不再矛盾。代理照片立即可用,最终处理在后台完成。
怎么开始:在 AVCapturePhotoOutput 上启用 isAutoDeferredPhotoDeliveryEnabled,处理 didFinishCapturingDeferredPhotoProxy 回调,将代理数据存入照片库。同时零快门延迟默认开启,无需额外配置。
3. 为视频通话应用添加反应特效面板
做什么:在视频通话或直播应用中增加一个反应特效按钮面板,让用户可以发送爱心、烟花等特效。
为什么值得做:反应特效是系统级功能,无需自行实现计算机视觉和动画渲染。用户可以用手势触发,也可以通过应用内的按钮触发。
怎么开始:在 Info.plist 中声明 NSCameraReactionEffectsEnabled,使用 AVCaptureReactionType.systemImageName 获取按钮图标,调用 performEffect(for:) 触发特效。通过 KVO 监听 reactionEffectsInProgress 在远程端显示特效图标。
4. 实现智能画质自适应
做什么:根据用户的拍摄行为动态调整画质优先级。检测到快速连拍时自动降低画质保持速度,单张拍摄时保持最高画质。
为什么值得做:isFastCapturePrioritizationEnabled 已经内置了这个逻辑,但你可以在 UI 层给用户更多控制权。
怎么开始:观察 AVCapturePhotoOutputReadinessCoordinator 的状态变化,结合用户的拍摄频率,在设置中提供”速度优先”和”画质优先”选项。
关联 Session
- Support external cameras in your iPadOS app — 在 iPadOS 应用中使用 Apple Studio Display 等外部相机
- What’s new in the Photos picker — 系统照片选择器的新改进,支持嵌入和连续选择
- What’s new in Background Assets — 后台下载资源,减少用户等待
- Meet SwiftUI for spatial computing — SwiftUI 在空间计算平台上的全新能力
评论
GitHub Issues · utterances