Swift:autoFocus / Expose和continuousAutoFocus / Exposure同时进行?

时间:2018-03-28 18:37:37

标签: swift camera focus avcapturedevice exposure

现在,在我的相机应用程序中,我让用户随时随地触摸以设置焦点和曝光,但我如何才能像Apple的相机应用程序那样获得两全其美?

例如,用户可能想要触摸以关注前景中的某些内容,但如果场景变化足够,则应该返回到continuousAutoFocus。如果用户将相机指向灯光,它应该改变曝光以使其正确显示,然后当相机返回场景时,它应该再次固定曝光,因此它不会太暗。但是,他们仍然可以选择让它更轻或更暗,这取决于它们通过相机的视角触摸的内容。

现在,当视图出现时,我将默认值设置为屏幕中心:

func setDefaultFocusAndExposure() {

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

    if let device = AVCaptureDevice.default(for:AVMediaType.video) {
        do {
            try device.lockForConfiguration()
            if device.isFocusPointOfInterestSupported {
                print(focusPoint)
                device.focusPointOfInterest = focusPoint
                device.focusMode = AVCaptureDevice.FocusMode.autoFocus
            }
            if device.isExposurePointOfInterestSupported {
                device.exposurePointOfInterest = focusPoint
                device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose
            }
            device.unlockForConfiguration()

        } catch {
            // Handle errors here
            print("There was an error focusing the device's camera")
        }
    }

}

此外,我让用户根据触摸位置设置焦点和曝光:

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

    let bounds = UIScreen.main.bounds

    let touchPoint = touches.first! as UITouch
    let screenSize = bounds.size
    let focusPoint = CGPoint(x: touchPoint.location(in: view).y / screenSize.height, y: 1.0 - touchPoint.location(in: view).x / screenSize.width)

    if let device = AVCaptureDevice.default(for:AVMediaType.video) {
        do {
            try device.lockForConfiguration()
            if device.isFocusPointOfInterestSupported {
                device.focusPointOfInterest = focusPoint
                device.focusMode = AVCaptureDevice.FocusMode.autoFocus
            }
            if device.isExposurePointOfInterestSupported {
                device.exposurePointOfInterest = focusPoint
                device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose
            }
            device.unlockForConfiguration()

        } catch {
            // Handle errors here
            print("There was an error focusing the device's camera")
        }
    }
}

1 个答案:

答案 0 :(得分:4)

想出来。首先,我在myViewDidAppear上调用一个方法来设置我的默认焦点和曝光模式:

@objc func setDefaultFocusAndExposure() {

    if let device = AVCaptureDevice.default(for:AVMediaType.video) {
        do {
            try device.lockForConfiguration()
                device.isSubjectAreaChangeMonitoringEnabled = true
                device.focusMode = AVCaptureDevice.FocusMode.continuousAutoFocus
                device.exposureMode = AVCaptureDevice.ExposureMode.continuousAutoExposure
            device.unlockForConfiguration()

        } catch {
            // Handle errors here
            print("There was an error focusing the device's camera")
        }
    }
}

这里的诀窍是不要将autoFocus与continuousAutoFocus混淆。这种方式默认情况下它会不断观察场景并设置焦点和曝光。另外isSubjectAreaChangeMonitorEnabled是一个非常重要的位。这使您可以在场景改变焦点或曝光时注册通知以调用功能,以便您可以切换对焦模式。更多关于这一点。

触摸屏幕可以根据一个点设置焦点和曝光:

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

    let bounds = UIScreen.main.bounds

    let touchPoint = touches.first! as UITouch
    let screenSize = bounds.size
    let focusPoint = CGPoint(x: touchPoint.location(in: view).y / screenSize.height, y: 1.0 - touchPoint.location(in: view).x / screenSize.width)

    if let device = AVCaptureDevice.default(for:AVMediaType.video) {
        do {
            try device.lockForConfiguration()
            if device.isFocusPointOfInterestSupported {
                device.focusPointOfInterest = focusPoint
                device.focusMode = AVCaptureDevice.FocusMode.autoFocus
            }
            if device.isExposurePointOfInterestSupported {
                device.exposurePointOfInterest = focusPoint
                device.exposureMode = AVCaptureDevice.ExposureMode.autoExpose
            }
            device.unlockForConfiguration()

        } catch {
            // Handle errors here
            print("There was an error focusing the device's camera")
        }
    }
}

在viewDidLoad中注册通知,将焦点和曝光模式设置为连续。在这里,我只是调用设置连续默认设置的函数:

    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.setDefaultFocusAndExposure),
                                           name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange,
                                           object: nil)

别忘了删除NotificationCenter中的观察员:

deinit {
    NotificationCenter.default.removeObserver(self)
}