ios - 如何使相机输入图像与输出图像的比例相同?
问题描述:
我创建了一个自定义相机,与它的问题是当我拍照时它以不同的比例出来,然后当我拍照时。ios - 如何使相机输入图像与输出图像的比例相同?
实施例:
之前:
后:
通知图像已被几乎侧身压扁。我想解决这个问题。我希望最终结果与输入图像完全相同。
我已经创建了一个视图,它是屏幕的大小,并用它来制作相机的框架,然后我制作了一个图像视图,它与覆盖屏幕的大小相同,由于某些原因照片不同。
下面是用于我的相机类我的源代码:
#import "CameraViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface CameraViewController()
@end
@implementation CameraViewController {
BOOL isFront;
}
AVCaptureSession *session;
AVCaptureStillImageOutput *imageOutput;
@synthesize cancelButton;
-(BOOL)prefersStatusBarHidden {
return YES;
}
-(void)viewDidAppear:(BOOL)animated {
isFront = NO;
session = [[AVCaptureSession alloc]init];
[session setSessionPreset:AVCaptureSessionPresetPhoto];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if ([session canAddInput:deviceInput]) {
[session addInput:deviceInput];
}
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:session];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
CALayer *rootLayer = [[self view]layer];
[rootLayer setMasksToBounds:YES];
CGRect frame = self.captureFrame.frame;
[previewLayer setFrame:frame];
[rootLayer insertSublayer:previewLayer atIndex:0];
imageOutput = [[AVCaptureStillImageOutput alloc]init];
NSDictionary *outputSettings = [[NSDictionary alloc]initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[imageOutput setOutputSettings:outputSettings];
[session addOutput:imageOutput];
[session startRunning];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
cancelButton.hidden = YES;
}
- (IBAction)capture:(id)sender {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection * connection in imageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([port.mediaType isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
[imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer != NULL) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:imageData];
// Need to rescale image
if (isFront == NO) {
self.imageView.image = image;
cancelButton.hidden = NO;
}else if (isFront == YES)
//Need to flip image here
self.imageView.image = image;
cancelButton.hidden = NO;
}
}];
}
// Delete photo just taking
- (IBAction)cancelAction:(id)sender {
cancelButton.hidden = YES;
self.imageView.image = nil;
}
// Dismiss this viewcontroller
-(IBAction)backButton:(id)sender{
[[NSNotificationCenter defaultCenter] postNotificationName:@"DISMISSCAMERA"object:nil];
}
// Switch Camera
- (IBAction)switchCamera:(id)sender {
if(session)
{
if (isFront == NO) {
isFront = YES;
}else if (isFront == YES) {
isFront = NO;
}
//Indicate that some changes will be made to the session
[session beginConfiguration];
//Remove existing input
AVCaptureInput* currentCameraInput = [session.inputs objectAtIndex:0];
[session removeInput:currentCameraInput];
//Get new input
AVCaptureDevice *newCamera = nil;
if(((AVCaptureDeviceInput*)currentCameraInput).device.position == AVCaptureDevicePositionBack)
{
newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
}
else
{
newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
}
//Add input to session
NSError *err = nil;
AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:newCamera error:&err];
if(!newVideoInput || err)
{
NSLog(@"Error creating capture device input: %@", err.localizedDescription);
}
else
{
[session addInput:newVideoInput];
}
//Commit all the configuration changes at once
[session commitConfiguration];
}
}
// Find a camera with the specified AVCaptureDevicePosition, returning nil if one is not found
- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices)
{
if ([device position] == position) return device;
}
return nil;
}
@end
答
原来,这是问题:
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
我将它设置为这个代替:
[previewLayer setVideoGravity:AVLayerVideoGravityResize];
奇迹般有效。
差不多,你仍然有一些变形 –