web-dev-qa-db-ja.com

iOSをタップしてフォーカス

このコードを使用して、iOSカスタムカメラアプリでTap-to-Focusを実現しましたが、機能していません。これがコードです

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    let touchPer = touches.anyObject() as UITouch
    let screenSize = UIScreen.mainScreen().bounds.size
    var focus_x = touchPer.locationInView(self.view).x / screenSize.width
    var focus_y = touchPer.locationInView(self.view).y / screenSize.height

    if let device = captureDevice {
        if(device.lockForConfiguration(nil)) {
            device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus

            device.focusPointOfInterest = CGPointMake(focus_x, focus_y)
            device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
            device.unlockForConfiguration()
        }
    }
}
21
Krishna
 device.focusPointOfInterest = focusPoint
 device.focusMode = AVCaptureFocusMode.AutoFocus
 device.exposurePointOfInterest = focusPoint
 device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure

なぜこれが機能するのかはわかりませんが、機能しました。

8
Krishna

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)) {
            if device.focusPointOfInterestSupported {
                device.focusPointOfInterest = focusPoint
                device.focusMode = AVCaptureFocusMode.AutoFocus
            }
            if device.exposurePointOfInterestSupported {
                device.exposurePointOfInterest = focusPoint
                device.exposureMode = AVCaptureExposureMode.AutoExpose
            }
            device.unlockForConfiguration()
        }
    }
} 

x座標とy座標を交換し、x座標を0から1ではなく1から0に再マップする必要があることに注意してください—なぜそうなのかはわかりませんが、正しく機能させる必要があるようです(テストするのも少し難しいですが)

編集: Appleのドキュメント 座標変換の理由を説明しています。

さらに、デバイスは、関心のあるフォーカスポイントをサポートする場合があります。 focusPointOfInterestSupportedを使用してサポートをテストします。サポートされている場合は、focusPointOfInterestを使用してフォーカルポイントを設定します。 CGPointを渡します。ここで、{0,0}は画像領域の左上を表し、{1,1}は右下を表し、ホームボタンが右側にあります。これは、デバイスがポートレートモードの場合でも適用されます。 。

私の例では、.ContinuousAutoFocus.ContinuousAutoExposureを使用していましたが、ドキュメントには.AutoFocusが正しい選択であることが示されています。奇妙なことに、ドキュメントには.AutoExposeについての記載がありませんが、コードで使用しており、正常に動作します。

また、サンプルコードを変更して、.focusPointOfInterestSupportedおよび.exposurePointOfInterestSupportedテストを含めました。ドキュメントには、特定のフォーカス/露出モードでisFocusModeSupported:およびisExposureModeSupported:メソッドを使用してテストするかどうかも記載されています。設定する前に特定のデバイスで使用できますが、デバイスが関心のあるモードをサポートしている場合は、自動モードもサポートしていると思います。私のアプリではすべて正常に機能しているようです。

23
Cody

Swift 3.0ソリューション

コーディの答えをSwift 3で実用的なソリューションに変換しました。

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

    if let device = captureDevice {
        do {
            try device.lockForConfiguration()
            if device.isFocusPointOfInterestSupported {
                device.focusPointOfInterest = focusPoint
                device.focusMode = AVCaptureFocusMode.autoFocus
            }
            if device.isExposurePointOfInterestSupported {
                device.exposurePointOfInterest = focusPoint
                device.exposureMode = AVCaptureExposureMode.autoExpose
            }
            device.unlockForConfiguration()

        } catch {
            // Handle errors here
        }
    }
}
10
Devbot10

関心のあるフォーカスポイントを設定するためのより良い方法:

  • 最初に関心のあるポイントを計算します。

     let devicePoint: CGPoint = (self.previewView.layer as!  AVCaptureVideoPreviewLayer).captureDevicePointOfInterestForPoint(gestureRecognizer.locationInView(gestureRecognizer.view))
    
  • その後、関心のあるフォーカスポイントを設定します。

    let device: AVCaptureDevice! = self.videoDeviceInput!.device
    
        do {
            try device.lockForConfiguration()
    
            if device.focusPointOfInterestSupported && device.isFocusModeSupported(focusMode){
    
                device.focusPointOfInterest = devicePoint
                device.focusMode = focusMode
            }
    
            device.unlockForConfiguration()
    
        }catch{
            print(error)
        }
    
5
Yogendra Singh

メソッドを正しい順序で呼び出す必要があります。

if(device.lockForConfiguration(nil)) {

    device.focusPointOfInterest = CGPointMake(focus_x, focus_y)
    device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus

    device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
    device.unlockForConfiguration()
}

フォーカスモードを設定する前に、関心のあるポイントを設定してください。そうしないと、前の関心のあるポイントにフォーカスが移されます。

同じことがexposurePointOfInterestにも当てはまります。

0
Nicolas Buquet