1

In my camera app, I'm thinking of supporting tap to focus and meter. I have found, as a user, that my finger sometimes accidentally touches the screen somewhere, and it focuses there, so I want to undo it. In my app, I'm thinking of adding a Reset Focus button, which would undo the tap to focus: it would tell iOS to focus whereever it thinks is best (as it was before the tap to focus).

Does iOS offer an API for this?

When the user taps at a point, I can assign to focusPointOfInterest and exposurePointOfInterest in AVCaptureDevice. But I don't see functions clearFocusPointOfInterest() and clearExposurePointOfInterest(). How do I do this?

Kartick Vaddadi
  • 4,818
  • 6
  • 39
  • 55
  • I'm sure there is also a focus lock or something. IIRC the focus doesn't lock in place and so if the image changes it will refocus. – Fogmeister Feb 21 '17 at 08:21
  • Ok. Yeah. AVCaptureDevice has a focus mode. It will only lock focus in "locked" focus mode. – Fogmeister Feb 21 '17 at 08:24
  • There is no such thing. You could try to force the camera to a particular focal length. You can't "unfocus" a camera though. It will always be focussed at a particular distance. – Fogmeister Feb 21 '17 at 13:08
  • I updated the question to clarify. Thanks, @Fogmeister. – Kartick Vaddadi Feb 21 '17 at 14:32
  • Ok. What you need to do is use the focus mode. When you use the function "focusPointOfInterest" it will focus once. And then after a short time it will continue to auto focus. If you set the focus mode to locked then it will not go back to auto focus. So you don't need to clear the focal point or anything. The camera will do this automatically. – Fogmeister Feb 21 '17 at 14:46
  • After a short time, it will continue to autofocus only if the scene changes, which may not be the case. – Kartick Vaddadi Feb 21 '17 at 14:52
  • but if the camera is focussed on something then it won't change anyway. All the camera does is try to make sure it's focussed. It will refocus if it goes out of focus. But if it's in focus it won't change. The only way to make it change is to change the point of interest or move the camera around. It has no concept of WHAT it is focussing on. Only that it is in focus or not. – Fogmeister Feb 22 '17 at 08:21

1 Answers1

0

You need to set the focus to .continousAutoFocus, the exposure to .continuousAutoExposure, and the focal point to CGPoint(x:0.5,y:0.5). The following focus and autofocus code works for me.

    @IBAction private func doFocusAndExpose(_ gestureRecognizer: UITapGestureRecognizer) {
        let devicePoint = previewView.videoPreviewLayer.captureDevicePointConverted(fromLayerPoint: gestureRecognizer.location(in: gestureRecognizer.view))
        focus(with: .autoFocus, exposureMode: .autoExpose, at: devicePoint)
    }

    @IBAction private func doAutofocus(_ gestureRecognizer: UITapGestureRecognizer) {
        let devicePoint = CGPoint(x:0.5,y:0.5)
        focus(with: .continuousAutoFocus, exposureMode: .continuousAutoExposure, at: devicePoint)
    }

    private func focus(with focusMode: AVCaptureDevice.FocusMode,
                       exposureMode: AVCaptureDevice.ExposureMode,
                       at devicePoint: CGPoint) {

        sessionQueue.async {
            let device = self.videoDeviceInput.device
            do {
                try device.lockForConfiguration()

                if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(focusMode) {
                    device.focusPointOfInterest = devicePoint
                    device.focusMode = focusMode
                }

                if device.isExposurePointOfInterestSupported && device.isExposureModeSupported(exposureMode) {
                    device.exposurePointOfInterest = devicePoint
                    device.exposureMode = exposureMode
                }

                device.unlockForConfiguration()
            } catch {
                print("Could not lock device for configuration: \(error)")
            }
        }
    }
Melissa
  • 168
  • 1
  • 7