【问题标题】:Swift: autoFocus/Expose and continuousAutoFocus/Exposure at the same time?Swift:同时自动对焦/曝光和连续自动对焦/曝光?
【发布时间】:2018-09-07 13:42:57
【问题描述】:

现在,在我的相机应用程序中,我让用户触摸任意位置来设置焦点和曝光,但我怎样才能像 Apple 的相机应用程序一样获得两全其美的效果呢?

例如,用户可能希望通过触摸来关注前景中的某物,但如果场景变化足够大,它应该返回到连续自动对焦。同样,如果用户将相机对准灯光,它应该改变曝光以使其正确显示,然后当相机返回场景时,它应该再次修复曝光,使其不会太暗。但是,他们仍然可以选择将其调亮或调暗,具体取决于他们在相机视野中触摸的内容。

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

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

【问题讨论】:

    标签: swift camera focus avcapturedevice exposure


    【解决方案1】:

    想通了。首先我在 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")
            }
        }
    }
    

    这里的诀窍是不要将自动对焦与连续自动对焦混淆。默认情况下,它会不断观察场景并设置焦点和曝光。另外 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)
    }
    

    【讨论】:

    • 这在前 2 次运行中对我有用,然后停止对焦和设置曝光。可能是什么原因
    • 对于您的设备,请确保调用 device.unlockForConfiguration()
    • 我正在调用它。我不确定这里出了什么问题。我什至使用了手势识别器
    猜你喜欢
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    相关资源
    最近更新 更多