使用Swift将相机焦点设置在点击点上

8ljdwjyq  于 2023-08-02  发布在  Swift
关注(0)|答案(7)|浏览(112)

在Swift中使用相机的API似乎是一个但不同的,我很难将相机聚焦在一个点上。当用户点击屏幕时,我希望相机聚焦在那个点
下面是我的代码:

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

字符串
但似乎行不通。
任何建议都非常欢迎!

ma8fv8wu

ma8fv8wu1#

来自@ryantxr的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
            }
        }
    }
}

字符串

ygya80vv

ygya80vv2#

更好的解决方案,因为它适用于所有videoGravity模式,并且在预览层纵横比与设备比率不同时也能正常工作:

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
}

字符串

sr4lhrrt

sr4lhrrt3#

更新了@Code for 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
            }
        }
    }
}

字符串

euoag5mw

euoag5mw4#

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

字符串

6pp0gazn

6pp0gazn5#

我使用AVFoundation库和一个 Package 器,相机管理器。我分享到代码示例。你可以调整你的项目。顺便说一句,你不能用前置摄像头对焦相机。它不支持它。您只能调整前置摄像头的曝光。用稀有相机,你可以做到。

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

字符串

nzk0hqpo

nzk0hqpo6#

结果很简单:

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

字符串

b1uwtaje

b1uwtaje7#

这个问题可能是iOS点击焦点的重复,在那里我发布了这个(希望是明确的)对我有效的解决方案:
使用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()
        }
    }
}

字符串
请注意,我必须交换xy坐标,并将x坐标从1重新Map到0而不是0到1 -不知道为什么会这样,但似乎有必要让它正确工作(尽管测试它也有点棘手)。

相关问题