Iphone 拍摄照片时切换AVCaptureSession预设
我当前的设置如下(基于来自的ColorTrackingCamera项目): 我正在使用一个Iphone 拍摄照片时切换AVCaptureSession预设,iphone,ios,avfoundation,Iphone,Ios,Avfoundation,我当前的设置如下(基于来自的ColorTrackingCamera项目): 我正在使用一个AVCaptureSession设置为AVCaptureSessionPreset640x480,我让输出作为纹理在OpenGL场景中运行。然后,该纹理由片段着色器操纵 我需要这个“低质量”预设,因为我想在用户预览时保持高帧率。然后,当用户捕获静态照片时,我希望切换到更高质量的输出 首先,我想我可以更改AVCaptureSession上的sessionPreset,但这会迫使相机重新聚焦,从而破坏可用性 [
AVCaptureSession
设置为AVCaptureSessionPreset640x480
,我让输出作为纹理在OpenGL场景中运行。然后,该纹理由片段着色器操纵
我需要这个“低质量”预设,因为我想在用户预览时保持高帧率。然后,当用户捕获静态照片时,我希望切换到更高质量的输出
首先,我想我可以更改AVCaptureSession
上的sessionPreset
,但这会迫使相机重新聚焦,从而破坏可用性
[captureSession beginConfiguration];
captureSession.sessionPreset = AVCaptureSessionPresetPhoto;
[captureSession commitConfiguration];
目前我正在尝试向AVCaptureSession添加第二个AVCaptureStillImageOutput
,但是我得到了一个空的像素缓冲区,所以我觉得我有点卡住了
以下是我的会话设置代码:
...
// Add the video frame output
[captureSession beginConfiguration];
videoOutput = [[AVCaptureVideoDataOutput alloc] init];
[videoOutput setAlwaysDiscardsLateVideoFrames:YES];
[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
[videoOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
if ([captureSession canAddOutput:videoOutput])
{
[captureSession addOutput:videoOutput];
}
else
{
NSLog(@"Couldn't add video output");
}
[captureSession commitConfiguration];
// Add still output
[captureSession beginConfiguration];
stillOutput = [[AVCaptureStillImageOutput alloc] init];
if([captureSession canAddOutput:stillOutput])
{
[captureSession addOutput:stillOutput];
}
else
{
NSLog(@"Couldn't add still output");
}
[captureSession commitConfiguration];
// Start capturing
[captureSession setSessionPreset:AVCaptureSessionPreset640x480];
if(![captureSession isRunning])
{
[captureSession startRunning];
};
...
以下是我的捕获方法:
- (void)prepareForHighResolutionOutput
{
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
[stillOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(imageSampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
int width = CVPixelBufferGetWidth(pixelBuffer);
int height = CVPixelBufferGetHeight(pixelBuffer);
NSLog(@"%i x %i", width, height);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}];
}
(宽度
和高度
结果为0)
我已经通读了AVFoundation文档,但似乎没有学到一些基本的东西。我找到了解决具体问题的方法。我希望它可以作为一个指南,如果有人偶然发现同样的问题 帧率显著下降的原因与像素格式之间的内部转换有关。明确设置像素格式后,帧速率增加 在我的情况下,我使用以下方法创建BGRA纹理:
// Let Core Video create the OpenGL texture from pixelbuffer
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache, pixelBuffer, NULL,
GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA,
GL_UNSIGNED_BYTE, 0, &videoTexture);
因此,当我设置AVCaptureStillImageOutput
实例时,我将代码更改为:
// Add still output
stillOutput = [[AVCaptureStillImageOutput alloc] init];
[stillOutput setOutputSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
if([captureSession canAddOutput:stillOutput])
{
[captureSession addOutput:stillOutput];
}
else
{
NSLog(@"Couldn't add still output");
}
我希望有一天这能帮助别人;) 您需要以多快的速度进行此预览?在视频预览运行(iOS 4.3+支持)的情况下,使用AVCaptureStillImageOutput,我可以在视频预览的输入帧上看到20 FPS。这并不是摄像机的30 FPS,但对于你想要拍摄的场景的预览来说已经足够了。好吧,几分钟前我找到了一个解决方案。我现在使用的是
AVCaptureStillImageOutput
预设,但我必须明确设置outputSettings
,以避免颜色空间之间的转换。我会马上把它作为一个答案发布。我正在尝试你的代码,但我仍然在点击640x480。可能有什么更新吗?我的代码中也有类似的情况,我正在拍摄640x480源,但是我想拍一张高分辨率的照片。不幸的是,即使添加了setOutputSettings:
参数,我仍然得到了零的宽度和高度。你能帮忙吗?请告诉我你是如何获得高质量的产品的?您的预设是AVCaptureSessionPreset640x480…请提供最终代码。我不知道在哪里使用CVOpenGlestExtractRecacheCreateTextureFromImage