iOS - Positioning a custom overlay on camera (vertical alignment). Size of top black bar
Asked Answered
D

1

6

I'm searching a programmatic solution to following problem: I want to draw a custom overlay on camera (iOS). And I want it to be vertically central on the camera output view. I've accomplished to draw my custom view centrically relatively to the screen, but not to the camera picture.

To do that, I need to get the size of the top black bar. How can I get it?

The size of top and bottom bars are not equal, that's why the picture I get has this annoying y-offset to the bottom.

Before shooting a pic

Notice the offset of the resulting pic: After shooting a pic

Disulfiram answered 19/5, 2015 at 15:12 Comment(6)
Set up an AVCaptureSession and attach a AVCaptureVideoPreviewLayer, then you will have full control over the size and placement of the camera view.Pyrope
The thing is, I'll have only the camera view, which is ok, but I also want to have all the functionality that UIImagePickerController offers. I would like to just know where does this view controller place its camera viewDisulfiram
AVCaptureSession has everything UIImagePickerController offers plus much much more. The UIImagePickerController is intended as a simple way to add a standard camera, not for detailed control. The layout of the will probably look different on different hardware.Pyrope
@BogdanWeidmann I am facing similar issue,, Any solution to this issue ?Optimistic
@Dave, I used the AVFoundation instead of UIImagePickerController, it turns out to be fairly easy. If you want, I can share some code with youDisulfiram
If possible, please share some code as answer to this question... it will be great :) thnxOptimistic
D
2

OK guys, I ended up using AVFoundation, which in the end was even better solution as it is customizable. I had self.fullScreenImageView and self.previewLayer as class properties. You need to write your own code implementing the buttons and the code of taking a camera shot. Here you can play around with the quality of the photo to get optimal size/quality. I used 0.6, but you can choose whatever you want.

@import MobileCoreServices;
@import AVFoundation;

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    [self.view setBackgroundColor:[UIColor blackColor]];

    self.fullScreenImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    self.fullScreenImageView.contentMode = UIViewContentModeScaleAspectFit;
    [self.fullScreenImageView setCenter:self.view.center];

        AVCaptureSession *captureSession = [[AVCaptureSession alloc] init];
        captureSession.sessionPreset = AVCaptureSessionPresetHigh;
        AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if (captureDevice) {
            NSError *error;
            AVCaptureDeviceInput *captureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error];
            if (!error && [captureSession canAddInput:captureDeviceInput]) {
                [captureSession addInput:captureDeviceInput];
            }
        }

        AVCaptureStillImageOutput *stillImageOutput = [AVCaptureStillImageOutput new];
        [stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG,
                                              AVVideoQualityKey : @(0.6)}];
        [captureSession addOutput:stillImageOutput];

        self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
        [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
        self.previewLayer.frame = self.fullScreenImageView.bounds;
        self.previewLayer.position = CGPointMake(CGRectGetMidX(self.fullScreenImageView.bounds), CGRectGetMidY(self.fullScreenImageView.bounds));
        [self.fullScreenImageView.layer addSublayer:self.previewLayer];
        [captureSession startRunning];

        CGRect circleRect = CGRectMake(0, (self.fullScreenImageView.bounds.size.height - self.fullScreenImageView.bounds.size.width) / 2, self.fullScreenImageView.bounds.size.width, self.fullScreenImageView.bounds.size.width);
        UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:circleRect];
        CAShapeLayer *ringLayer = [CAShapeLayer layer];
        ringLayer.path = circle.CGPath;
        ringLayer.fillColor = nil;
        ringLayer.strokeColor = [UIColor redColor].CGColor;
        ringLayer.lineWidth = 2.0;
        ringLayer.lineDashPattern = @[@5.0, @10.0];
        [self.fullScreenImageView.layer addSublayer:ringLayer];

        [self.navigationController setToolbarHidden:NO];
        [self.navigationController.toolbar setBarStyle:UIBarStyleBlackOpaque];
        [self.navigationController.toolbar setTintColor:[UIColor whiteColor]];
        // Add here some buttons, which are standard UIBarButtonItems

    [self.view addSubview:self.fullScreenImageView];
}
Disulfiram answered 17/7, 2015 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.