AVCaptureSession预设照片和AVCaptureVideoPreviewLayer尺寸

时间:2013-01-04 08:51:31

标签: objective-c ios camera

我初始化AVCaptureSession并将其预设为:

AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init];
if (YES==[newCaptureSession canSetSessionPreset:AVCaptureSessionPresetPhoto]) {
    newCaptureSession.sessionPreset = AVCaptureSessionPresetPhoto;
} else {
    // Error management
}

然后我设置了AVCaptureVideoPreviewLayer

self.preview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/*426*/)];
CALayer *previewLayer = preview.layer;
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
captureVideoPreviewLayer.frame = previewLayer.frame;
[previewLayer addSublayer:captureVideoPreviewLayer];
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspect;

我的问题是:
如何在屏幕上显示所有CGSize图层所需的确切captureVideoPreviewLayer?更准确地说,我需要AVLayerVideoGravityResizeAspect的高度使AVCaptureVideoPreviewLayer适合preview.size
我尝试获得适合的AVCaptureVideoPreviewLayer尺寸。

非常感谢你的帮助

4 个答案:

答案 0 :(得分:8)

经过AVCaptureSessionPresetPhoto的一些研究后,AVCaptureVideoPreviewLayer尊重iPhone相机的3/4比例。因此,通过简单的微积分很容易获得正确的高度 例如,如果宽度 320 ,则适当的高度为:
320 * 4/3 = <强> 426.6

答案 1 :(得分:1)

如果我理解正确,你会尝试获得宽度和宽度。当前视频会话的高度 您可以从AVCaptureOutput的outputSettings字典中获取它们。 (使用AVVideoWidthKey&amp; AVVideoHeightKey)。

e.g。

NSDictionary* outputSettings = [movieFileOutput outputSettingsForConnection:videoConnection];
CGSize videoSize = NSMakeSize([[outputSettings objectForKey:AVVideoWidthKey] doubleValue], [[outputSettings objectForKey:AVVideoHeightKey] doubleValue]);

<强>更新
另一个想法是从预览会话的图像缓冲区中获取帧大小 实现AVCaptureVideoDataOutputSampleBufferDelegate方法captureOutput:didOutputSampleBuffer:fromConnection: (不要忘记设置AVCaptureOutput的委托)

- (void)captureOutput:(AVCaptureFileOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
{
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    if(imageBuffer != NULL)
    {
        CGSize imageSize = CVImageBufferGetDisplaySize(imageBuffer);
        NSLog(@"%@", NSStringFromSize(imageSize));
    }
}

答案 2 :(得分:1)

Weischel的代码对我不起作用。这个想法奏效了,但代码却没有。这是有效的代码:

    // Get your AVCaptureSession somehow. I'm getting mine out of self.videoCamera, which is a GPUImageVideoCamera
    // Get the appropriate AVCaptureVideoDataOutput out of the capture session. I only have one session, so it's easy.

    AVCaptureVideoDataOutput *output = [[[self.videoCamera captureSession] outputs] lastObject];
    NSDictionary* outputSettings = [output videoSettings];

    // AVVideoWidthKey and AVVideoHeightKey did not work. I had to use these literal keys.
    long width  = [[outputSettings objectForKey:@"Width"]  longValue]; 
    long height = [[outputSettings objectForKey:@"Height"] longValue];

    // video camera output dimensions are always for landscape mode. Transpose if your camera is in portrait mode.
    if (UIInterfaceOrientationIsPortrait([self.videoCamera outputImageOrientation])) {
        long buf = width;
        width = height;
        height = buf;
    }

    CGSize outputSize = CGSizeMake(width, height);

答案 3 :(得分:1)

感谢gsempe的回答。我从小时起就遇到了同样的问题:) 我用这个代码解决了它,以横向模式将其置于屏幕中:

CGRect layerRect = [[[self view] layer] bounds];
[PreviewLayer setBounds:CGRectMake(0, 0, 426.6, 320)];
[PreviewLayer setPosition:CGPointMake(CGRectGetMidY(layerRect), CGRectGetMidX(layerRect))];

请注意,我必须反转CGRectGetMidY()和CGRectGetMidX()函数才能在屏幕中显示居中图层。

谢谢,

儒略