Search code examples
iosswiftavcapturesession

How to implement 2x zoom from camera app with AVCaptureVideoPreviewLayer


I have a AVCaptureVideoPreviewLayerin my app that works well and is showing the same preview video as the camera app. I would like to implement the 2x zoom functionality of the camera app. How do I do this?

Basically I want my previewlayer to change the video feed to same scale as what you see in the camera app when you tap on the 1x icon to change it to 2x.

setting up preview layer

func startSession(){
    captureSession = AVCaptureSession()
    captureSession?.sessionPreset = AVCaptureSessionPresetPhoto
    
    let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
    
    // Catch error using the do catch block
    do {
        let input = try AVCaptureDeviceInput(device: backCamera)
        if (captureSession?.canAddInput(input) != nil){
            captureSession?.addInput(input)
            
            // Setup the preview layer
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
            tempImageView.layer.addSublayer(previewLayer!)
            captureSession?.startRunning()
            
            // Set up AVCaptureVideoDataOutput
            let dataOutput = AVCaptureVideoDataOutput()
            dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_32BGRA as UInt32)]
            dataOutput.alwaysDiscardsLateVideoFrames = true
            
            if (captureSession?.canAddOutput(dataOutput) == true) {
                captureSession?.addOutput(dataOutput)
            }
            let queue = DispatchQueue(label: "com.bigbob.videoQueue")
            dataOutput.setSampleBufferDelegate(self, queue: queue)
        }
    } catch _ {
        print("Error setting up camera!")
    }

Solution

  • Set the videoZoomFactor of your AVCaptureDevice.defaultDevice and the preview layer's zoom will follow suit. Note Swift 4 it is now called AVCaptureDevice.default.

    do {
        try backCamera?.lockForConfiguration()
        let zoomFactor:CGFloat = 2
        backCamera?.videoZoomFactor = zoomFactor
        backCamera?.unlockForConfiguration()
    } catch {
           //Catch error from lockForConfiguration
    }