Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVFoundation, cut off edges in the preview layer

Tags:

ios

I am developing some iOS app, where I need to do some camera scanning. This is my first experience with AVFoundation, previously I developed camera apps with UIImagePickerController, but AVFoundation seems to be more powerful.

The problem is that it cuts off edges in the preview layer, regardless of that I set preview layer's frame as big as view controller's one.

This is my code:

AVCaptureSession *captureSession = [[AVCaptureSession alloc] init];
    AVCaptureDevice *photoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:photoCaptureDevice error:&error];
    if(videoInput){
        [captureSession addInput:videoInput];
        [captureSession startRunning];
        NSLog(@"ok");
    }   
    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
    previewLayer.frame = self.view.bounds;
    NSLog(@"%f %f", previewLayer.frame.size.width, previewLayer.frame.size.height);
    [self.view.layer addSublayer:previewLayer];

Would be very thankful for a help, Artem

like image 935
Artem Avatar asked Oct 22 '11 13:10

Artem


2 Answers

This is because the aspect ratio of the video that you're capturing is different to that of the screen. There's not much you can do - it's either letter boxing or non uniform scaling of the image. You can throw away some pixels on the short edge, which is probably what UIImagePickerController does.

If you want this behaviour, try setting

  previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
like image 173
Rhythmic Fistman Avatar answered Nov 03 '22 16:11

Rhythmic Fistman


Actually the solution was pretty simple, as Rhythmic Fistman mentioned there is a property in AVCaptureVideoPreviewLayer - videoGravity. So to fit the preview layer in your custom view:

previewLayer.frame = self.view.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
// Specifies that the player should preserve the video’s aspect ratio and fill the layer’s bounds.

or

previewLayer.videoGravity = AVLayerVideoGravityResize; 
// Specifies that the video should be stretched to fill the layer’s bounds.
like image 9
Artem Avatar answered Nov 03 '22 17:11

Artem