我试图在iPhone 5s上以最高分辨率(AVCaptureSessionPresetPhoto)拍摄多张照片。我尝试使用以下代码:
dispatch_semaphore_t sync = dispatch_semaphore_create(0);
while( [self isBurstModeEnabled] == YES )
{
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
if (imageSampleBuffer != NULL)
{
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
NSString *videoThumbPath = [NSString
stringWithFormat:@"%@/img%d.png",
burstFolderPath,
index];
[imageData writeToFile:videoThumbPath atomically:YES];
if( 0 == index )
{
[self NSLogPrint:[NSString stringWithFormat:@"Created photo at %@",videoThumbPath]];
}
}
dispatch_semaphore_signal(sync);
}];
dispatch_semaphore_wait(sync, DISPATCH_TIME_FOREVER);
}
使用此代码我每秒可以获得大约2张照片,无法接近原生相机应用程序的连拍模式。我究竟做错了什么?此外,我尝试使用上面的代码没有信号量,但在这种情况下,我有奇怪的行为,一些照片丢失(img0.png img1.png img3.png将存在,但img2.png将丢失)。使用第二种方法,性能会更好,但仍然不能与本机应用程序性能相媲美(在我的测试中,相机应用程序每秒会产生大约8.4张照片)。
答案 0 :(得分:15)
captureStillImageAsynchronouslyFromConnection:completionHandler:
不是Apple正在使用的爆发模式。
相反,Apple以全分辨率(<5>支持抓取视频帧)。以下是:
AVCaptureDevice将activeFormat
设置为完整的传感器分辨率,然后您从AVCaptureVideoDataOutputSampleBufferDelegate
captureOutput:didOutputSampleBuffer:fromConnection:
获取并处理每秒10帧,触发快门声音抓住每一帧。
对于不支持完整传感器尺寸分辨率视频的设备,您需要进行后备(较低分辨率图像或较慢的连拍模式)和/或想要支持iOS 7.x以上的任何东西。
请注意,您不能同时使用captureStillImageAsynchronouslyFromConnection:completionHandler:
,而不会产生一些非常意外的结果。这就是为什么你应该调用前一个completionHandler
的每个迭代(实际上,这是你的信号量正在做的事情)。此外,您可能希望从PNG切换为突发镜头的文件格式 - 它保存得非常慢并且需要大量系统资源 - 堆叠15或20个PNG可能会让您感到非常悲伤!
* 可能这样做,因为它当然可以使用私有API来实现相同的最终结果。
答案 1 :(得分:2)
在iOS 8及更高版本中将此方法用于连拍模式:
- (void)captureStillImageBracketAsynchronouslyFromConnection:(AVCaptureConnection *)connection withSettingsArray:(NSArray *)settings completionHandler:(void (^)(CMSampleBufferRef sampleBuffer, AVCaptureBracketedStillImageSettings *stillImageSettings, NSError *error))handler NS_AVAILABLE_IOS(8_0);