swiftsdkios8avcapture

AVCaptureVideoPreviewLayer and preview from camera position


I'm developing an app that permits user to takes photo. I've started using AVCam apple provides but i'm actually have a problem Simply i cannot position the camera layer where i want but it's positioned automatically on center of the View

enter image description here

On the left side you can see what i actually have, on the right side what i'd like to have. The View that contains the preview that comes from the camera is a UIView subclass and this is the code

class AVPreviewView : UIView {
    override class func layerClass() -> AnyClass {
        return AVCaptureVideoPreviewLayer.self
    }
    func session () -> AVCaptureSession {
        return (self.layer as AVCaptureVideoPreviewLayer).session
    }

    func setSession(session : AVCaptureSession) -> Void {
        (self.layer as AVCaptureVideoPreviewLayer).session = session;
        (self.layer as AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspect;

    }
}

Any help is appreciated


Solution

  • First get your screen size so you can calculate the aspect ratio

        let screenWidth = UIScreen.mainScreen().bounds.size.width
        let screenHeight = UIScreen.mainScreen().bounds.size.height
        var aspectRatio: CGFloat = 1.0
    
        var viewFinderHeight: CGFloat = 0.0
        var viewFinderWidth: CGFloat = 0.0
        var viewFinderMarginLeft: CGFloat = 0.0
        var viewFinderMarginTop: CGFlaot = 0.0
    

    Now calculate the size of the preview layer.

        func setSession(session : AVCaptureSession) -> Void {
    
            if screenWidth > screenHeight {
                aspectRatio = screenHeight / screenWidth * aspectRatio
                viewFinderWidth = self.bounds.width
                viewFinderHeight = self.bounds.height * aspectRatio
                viewFinderMarginTop *= aspectRatio
            } else {
                aspectRatio = screenWidth / screenHeight
                viewFinderWidth = self.bounds.width * aspectRatio
                viewFinderHeight = self.bounds.height
                viewFinderMarginLeft *= aspectRatio
            }
    
            (self.layer as AVCaptureVideoPreviewLayer).session = session;
    

    Set the layer's videoGravity to AVLayerVideoGravityResizeAspectFill so that the layer stretches to fill given your custom view.

            (self.layer as AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspectFill;
    

    Finally, set the frame of your preview layer to the values calculated above with any offset that you like.

            (self.layer as AVCaptureVideoPreviewLayer).frame = CGRectMake(viewFinderMarginLeft, viewFinderMarginTop, viewFinderWidth, viewFinderHeight)
    
        }
    

    This may take some tweaking since I haven't tested it live, but you should be able to create a more flexible VideoPreviewArea delimited by the bounds of your APPreviewView.