Set the camera focus to the connection point using Swift

The API for using the camera in swift seems completely different, and it's hard for me to focus the camera on a point. When the user deletes the screen, I want the camera to focus on this point.

This is my code:

 func focusCamera(point:CGPoint)
    {
        var screenRect:CGRect = bounds
        var focusX = Float(point.x/screenRect.width)
        var focusY = Float(point.y/screenRect.height)

        _currentDevice.lockForConfiguration(nil)
        _currentDevice.setFocusModeLockedWithLensPosition(focusX)
        {
            time in
            self._currentDevice.unlockForConfiguration()
        }

        _currentDevice.setFocusModeLockedWithLensPosition(focusY)
        {
                time in
                self._currentDevice.unlockForConfiguration()
        }
    }

But it does not seem to work.

Any suggestions are more than welcome!

+4
source share
7 answers

It turns out to be very simple:

_currentDevice.lockForConfiguration(nil)
_currentDevice.focusPointOfInterest = tap.locationInView(self)
_currentDevice.unlockForConfiguration()
0
source

Updated answer from @ryantxr for Swift 3:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let screenSize = videoView.bounds.size
        if let touchPoint = touches.first {
            let x = touchPoint.location(in: videoView).y / screenSize.height
            let y = 1.0 - touchPoint.location(in: videoView).x / screenSize.width
            let focusPoint = CGPoint(x: x, y: y)

            if let device = captureDevice {
                do {
                    try device.lockForConfiguration()

                    device.focusPointOfInterest = focusPoint
                    //device.focusMode = .continuousAutoFocus
                    device.focusMode = .autoFocus
                    //device.focusMode = .locked
                    device.exposurePointOfInterest = focusPoint
                    device.exposureMode = AVCaptureExposureMode.continuousAutoExposure
                    device.unlockForConfiguration()
                }
                catch {
                    // just ignore
                }
            }
        }
    }
+9
source

@Code Swift 2.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let screenSize = videoView.bounds.size
    if let touchPoint = touches.first {
        let x = touchPoint.locationInView(videoView).y / screenSize.height
        let y = 1.0 - touchPoint.locationInView(videoView).x / screenSize.width
        let focusPoint = CGPoint(x: x, y: y)

        if let device = captureDevice {
            do {
                try device.lockForConfiguration()

                device.focusPointOfInterest = focusPoint
                //device.focusMode = .ContinuousAutoFocus
                device.focusMode = .AutoFocus
                //device.focusMode = .Locked
                device.exposurePointOfInterest = focusPoint
                device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
                device.unlockForConfiguration()
            }
            catch {
                // just ignore
            }
        }
    }
}
+2

, , iOS tap to focus, (, ) , :

videoView: UIView cameraDevice: AVCaptureDevice :

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    var touchPoint = touches.first as! UITouch
    var screenSize = videoView.bounds.size
    var focusPoint = CGPoint(x: touchPoint.locationInView(videoView).y / screenSize.height, y: 1.0 - touchPoint.locationInView(videoView.x / screenSize.width)

    if let device = cameraDevice {
        if(device.lockForConfiguration(nil)) {
            device.focusPointOfInterest = focusPoint
            device.focusMode = AVCaptureFocusMode.ContinuousAutoExposure
            device.exposurePointOfInterest = focusPoint
            device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
            device.unlockForConfiguration()
        }
    }
}

, x y x 1 0 0 1 - , , , , ( ).

+1

Swift 2.0

if let device = captureDevice {
  do { 
    try device.lockForConfiguration()
    device.focusPointOfInterest = focusPoint
    device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus
    device.exposurePointOfInterest = focusPoint
    device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
  } catch let error as NSError {
    print(error.localizedDescription)
  }
}
+1

AVFoundation , Camera Manager. . . , . . . .

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    let screenSize = cameraView.bounds.size
    let frameSize:CGSize = view.frame.size
    if let touchPoint = touches.first {

        var location:CGPoint = touchPoint.locationInView(cameraView)

        if cameraManager.cameraDevice == .Front {
            print("Front camera is used")

            location.x = frameSize.width - location.x;
        }
        else {
            print("Back camera is used")
        }

        let x = location.x / frameSize.width
        let y = 1.0 - (location.x / frameSize.width)

        let focusPoint = CGPoint(x: x, y: y)

        print("POINT : X: \(x), Y: \(y)")


        let captureDevice = (AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice]).filter{$0.position == .Back}.first

        if let device = captureDevice {
            do {
                try device.lockForConfiguration()

                let support:Bool = device.focusPointOfInterestSupported

                if support  {

                    print("focusPointOfInterestSupported: \(support)")

                    device.focusPointOfInterest = focusPoint

                    // device.focusMode = .ContinuousAutoFocus
                    device.focusMode = .AutoFocus
                    // device.focusMode = .Locked

                    device.unlockForConfiguration()

                    print("Focus point was set successfully")
                }
                else{
                    print("focusPointOfInterestSupported is not supported: \(support)")
                }
            }
            catch {
                // just ignore
                print("Focus point error")
            }
        }
    }
}
+1

The best solution, since it works correctly for all modes videoGravity, also when the aspect ratio of the preview is different from the ratio of the device:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    guard let touchPoint = touches.first else { return }

    // precondition: the videoView contains the previewLayer, and the frames of the two are being kept equal
    let touchPointInPreviewLayer = touchPoint.location(in: videoView)
    let focusPoint = previewLayer.captureDevicePointOfInterest(for: touchPointInPreviewLayer)

    // etc
}
+1
source

All Articles