如何让AVCaptureStillImageOutput与AVCaptureVideoPreviewLayer具有相同的宽高比?

时间:2015-07-29 11:22:59

标签: ios objective-c iphone avfoundation

我使用AVFoundation捕获图像。我使用AVCaptureVideoPreviewLayer在屏幕上显示相机Feed。此预览图层的框架获取具有动态尺寸的UIView的边界:

AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
CALayer *rootLayer = [self.cameraFeedView layer];
[rootLayer setMasksToBounds:YES];
CGRect frame = self.cameraFeedView.frame;
[previewLayer setFrame:frame];
previewLayer.frame = rootLayer.bounds;
[rootLayer insertSublayer:previewLayer atIndex:0];

我正在使用AVCaptureStillImageOutput来捕捉图片:

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection
                                              completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
                                                  if (imageDataSampleBuffer != NULL) {
                                                      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                                                      UIImage *capturedImage = [UIImage imageWithData:imageData];
                                                  }
                                              }];

我的问题是拍摄的图像大小与iPhone相机(1280x960 - 前置摄像头)相同,但我需要它与预览图层的宽高比相同。例如,如果预览图层的大小为150x100,我需要捕获的图像为960x640。对此有什么解决方案吗?

1 个答案:

答案 0 :(得分:1)

我也反击同样的问题。您必须裁剪或调整输出静止图像的大小。但你应该注意到输出仍然是尺度和图像方向。

预览图层方框

CGFloat width = CGRectGetWidth(self.view.bounds);
[self.captureVideoPreviewLayer setFrame:CGRectMake(0, 0, width, width)];
[self.cameraView.layer addSublayer:self.captureVideoPreviewLayer];

计算裁剪图像的框架

[self.captureStillImageOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
    NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
    UIImage *image = [[UIImage alloc] initWithData:data];

    CGRect cropRect = CGRectMake((image.size.height - image.size.width) / 2, 0, image.size.width, image.size.width);
    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; // always UIImageOrientationRight
    CGImageRelease(imageRef);
}];