Lightsout
Lightsout

Reputation: 3757

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!")
    }

Upvotes: 5

Views: 4689

Answers (2)

Ethan Allen
Ethan Allen

Reputation: 14835

Here's a bit of an updated answer that fist checks to make sure the zoom factor is available before you even attempt to set it. The will prevent possibly unneeded exception catches and you can adjust the zoom check and set easily with one variable.

if let captureDevice = AVCaptureDevice.default(for: AVMediaType.video) {
    let zoomFactor : CGFloat = 2
    if (captureDevice.maxAvailableVideoZoomFactor >= zoomFactor) {
        try? captureDevice.lockForConfiguration()
        captureDevice.videoZoomFactor = zoomFactor
        captureDevice.unlockForConfiguration()
    }
}

Upvotes: 0

Lightsout
Lightsout

Reputation: 3757

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
}

Upvotes: 9

Related Questions