AVCapturePhotoCaptureDelegate 监视进度和从AVCapturePhotoOutput
接收结果的方法。
要拍摄照片,需要调用AVCapturePhotoOutput
实例的- capturePhotoWithSettings:delegate:
方法;AVCapturePhotoOutput
调用的协议方法取决于拍摄照片时的设置AVCapturePhotoSettings
。此协议中的所有方法在编译时都是可选的,但在运行时,委托对象必须根据照片设置响应某些方法:
- 如果拍摄静态照片(通过指定图像格式或文件类型), 必须实现
- captureOutput:didFinishProcessingPhoto:error:
方法, - 如果拍摄动态照片(通过将
livePhotoMovieFileURL
属性设置为非零值),必须实现-captureOutput:didFinishProcessingLivePhotoToMovieFileAtURL:duration:photoDisplayTime:resolvedSettings:error:
方法。
当调用- capturePhotoWithSettings:delegate:
方法时,必须实现上述某一个协议方法,否则会引发异常。
每次调用- capturePhotoWithSettings:delegate:
方法时,必须使用唯一的AVCapturePhotoSettings
对象。当照片输出调用协议方法时,它会提供一个AVCaptureResolvedPhotoSettings
对象,其uniqueID
与请求捕获的照片设置的属性相匹配。进行多次拍摄时,使用此uniqueID
来确定哪些协议方法调用对应于哪些请求。
每次调用- capturePhotoWithSettings:delegate:
方法时,照片输出始终调用“监控拍摄进度”中四个方法各一次。 对于“接收拍摄结果”中的三个方法,可能会多次被调用,或者根本不被调用,具体取决于照片设置AVCapturePhotoSettings
。
1、监控拍摄进度
每次调用- capturePhotoWithSettings:delegate:
方法时,下述方法都会被调用一次。
1.1、拍摄输出已解析设置,并将很快开始拍摄过程
- (void)captureOutput:(AVCapturePhotoOutput *)output
willBeginCaptureForResolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings;
当AVCapturePhotoOutput
调用- capturePhotoWithSettings:delegate:
方法,已提交选择设置AVCapturePhotoSettings
并将很快开始捕获过程时,它会尽可能早的调用此方法,让我们知道对于与同一捕获相关的其他协议方法调用会发生什么。该方法有两个参数:
- 参数
resolvedSettings
:描述用于此拍摄的设置的对象。将此对象的uniqueID
值与拍摄照片时设置对象AVCapturePhotoSettings
的uniqueID
属性相匹配,以确定此委托调用对应的捕获请求。还可以使用此对象找出照片输出为自动设置选择的值。
使用此方法及其提供的AVCaptureResolvedPhotoSettings
可以尽早找到AVCapturePhotoOutput
为自动设置AVCapturePhotoSettings
选择的值,以及捕获的图像和电影的输出尺寸。例如,如果请求将flashMode
属性设置为AVCaptureFlashModeAuto
进行拍摄,则已解析的照片设置flashEnabled
属性指示在拍摄期间是否会触发闪光灯。
1.2、即将拍摄照片
- (void)captureOutput:(AVCapturePhotoOutput *)output
willCapturePhotoForResolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings;
AVCapturePhotoOutput
调用此方法尽可能接近拍摄的初始时刻。如果启用了快门声,则在AVCapturePhotoOutput
开始播放快门声后立即调用此方法。
注意:实时照片捕捉禁用快门声音。在某些地方,设备的静音开关可以禁用快门声音。
1.3、已拍摄照片
一旦拍摄的第一步结束,即在摄影曝光时间结束时,AVCapturePhotoOutput
就会调用此方法。
- (void)captureOutput:(AVCapturePhotoOutput *)output
didCapturePhotoForResolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings;
1.4、拍摄照片已完成
当整个拍摄过程完成时,AVCapturePhotoOutput
会调用此方法,并且不会再为此拍摄请求发送任何协议消息。
- (void)captureOutput:(AVCapturePhotoOutput *)output
didFinishCaptureForResolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings
error:(NSError *)error;
在这里清除已分配的与此拍摄请求相关的任何资源。
2、接收拍摄结果
每次调用- capturePhotoWithSettings:delegate:
方法时,下述三个方法可能会多次被调用,或者根本不被调用,具体取决于照片设置AVCapturePhotoSettings
。
2.1、提供拍摄的图像以及照片产生的相关元数据
2.1.1、适配 iOS10.0 ~ iOS11.0
提供拍摄的JPEG等格式图像
- (void)captureOutput:(AVCapturePhotoOutput *)output
didFinishProcessingPhotoSampleBuffer:(CMSampleBufferRef)photoSampleBuffer
previewPhotoSampleBuffer:(CMSampleBufferRef)previewPhotoSampleBuffer
resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings
bracketSettings:(AVCaptureBracketedStillImageSettings *)bracketSettings
error:(NSError *)error NS_DEPRECATED_IOS(10_0, 11_0);
如果以JPEG等格式请求拍摄,则AVCapturePhotoOutput
会对拍摄请求中的每次曝光调用此方法一次。如果拍摄单个图像,则会调用此方法一次。如果要求使用多次曝光进行包围拍摄,则每次曝光都会调用一次此方法。
- 参数
photoSampleBuffer
包含捕获的照片的样本缓冲区,可以是未压缩的像素缓冲区或压缩的图像数据,以及计时信息和其他元数据。 - 参数
previewPhotoSampleBuffer
如果请求缩略图,则会显示一个样本缓冲区,其中包含所请求格式的缩略图照片。如果未请求预览传递,或者拍摄失败,则此参数为nil。 - 参数
bracketSettings
如果请求使用AVCapturePhotoBracketSettings
对多个图像进行括号捕获,则会在方括号内的静止图像设置对象中描述此委托调用对应的括号中的哪个图像。如果没有请求包围捕获,则此参数为nil。
提供RAW格式图像
如果请求拍摄RAW格式,则AVCapturePhotoOutput
会在拍摄请求中为每次曝光调用此方法一次。如果拍摄单个图像,则会调用此方法一次。如果要求使用多次曝光进行包围拍摄,则每次曝光都会调用一次此方法。
- (void)captureOutput:(AVCapturePhotoOutput *)output
didFinishProcessingRawPhotoSampleBuffer:(CMSampleBufferRef)rawSampleBuffer
previewPhotoSampleBuffer:(CMSampleBufferRef)previewPhotoSampleBuffer
resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings
bracketSettings:(AVCaptureBracketedStillImageSettings *)bracketSettings
error:(NSError *)error NS_DEPRECATED_IOS(10_0, 11_0)
2.1.2、适配 iOS11.0 及以后版本
- (void)captureOutput:(AVCapturePhotoOutput *)output
didFinishProcessingPhoto:(AVCapturePhoto *)photo
error:(NSError *)errorAPI_AVAILABLE(ios(11.0));
无论格式如何,使用此方法都可以接收拍摄照片的结果;该方法有三个参数:
- 参数
AVCapturePhoto *photo
:包含拍摄的图像像素缓冲区的对象,以及与照片一起捕获的任何元数据和附件(例如预览图像或深度图)。此参数始终为非零;即使拍摄失败,此对象仍包含预期捕获的元数据。
对于所有静止图像拍摄工作,建议使用此方法;如果请求深度数据传递,则需要使用此方法。当调用- capturePhotoWithSettings:delegate:
方法时,如果没有实现正确的协议方法,则照片输出会引发异常。
对于动态照片拍摄工作流,可以接收动态照片的静止图像组件。
对于要在拍摄请求中传递的每个主映像,AVCapturePhotoOutput
调用此方法一次。
如果以 RAW 和 processed formats
请求拍摄,则此方法将针对每种格式触发一次。
如果要求使用多次曝光进行包围拍摄,则此方法会在每次曝光时触发一次。
2.2、动态照片已完成拍摄
拍摄动态照片时,AVCapturePhotoOutput
会调用此方法
- (void)captureOutput:(AVCapturePhotoOutput *)output
didFinishRecordingLivePhotoMovieForEventualFileAtURL:(NSURL *)outputFileURL
resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings;
此时,动态照片内容尚未处理或写入存储。
使用此方法确定何时更改显示的UI以指示不再进行动态照片拍摄。例如,当用户按下快门按钮时,应用程序会显示“LIVE”图标,然后在拍摄动画结束时隐藏该图标。
每次拍摄动态照片时,AVCapturePhotoOutput
仅调用此方法一次。
2.3、动态照片产生的URL
调用该方法可以接收动态照片的拍摄结果;如果不拍摄动态照片,则无需实现此方法。
- (void)captureOutput:(AVCapturePhotoOutput *)output
didFinishProcessingLivePhotoToMovieFileAtURL:(NSURL *)outputFileURL
duration:(CMTime)duration
photoDisplayTime:(CMTime)photoDisplayTime
resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings
error:(NSError *)error;
- 参数
NSURL *outputFileURL
:写入动态照片内容的fileURL
。 - 参数
duration
:动态照片的持续时间。 - 参数
photoDisplayTime
:动态照片的静止图像部分所对应的时间戳。
当AVCapturePhotoOutput
调用此方法时,动态照片的影片组件已写入outputFileURL
参数指定的位置。
要将拍摄的动态照片添加到用户的照片库,需要使用PHAssetCreationRequest
类。 要使用照片库中的动态照片,需要使用PHLivePhoto
和PHLivePhotoView
类。 要在Web上显示动态照片内容,需要使用LivePhotosKit JS
框架。
如果拍摄动态照片,则必须实现此方法。 当调用- capturePhotoWithSettings:delegate:
方法时,如果没有实现该协议方法,则照片输出会引发异常。
每次拍摄动态照片时,AVCapturePhotoOutput
仅调用此方法一次。
本文涉及到的更多信息请阅读:
点击阅读 AVCaptureDevice
点击阅读 AVCaptureSession
点击阅读 AVCapturePhotoOutput
点击阅读 AVCapturePhotoCaptureDelegate
点击阅读 AVCapturePhotoSettings
点击阅读 AVCaptureResolvedPhotoSettings
点击阅读 AVCapturePhoto