iOS轻点焦点

我使用这个代码来实现在iOS自定义相机应用程序中的点击对焦,但它不工作。 这是代码

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

使用videoView: UIView显示video,以及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() } } } 

请注意,我必须交换xy坐标,并将x坐标从1重新映射到0,而不是0到1 – 不知道为什么应该是这种情况,但似乎有必要让它正常工作(尽pipe它有点棘手来testing它)

编辑: 苹果的文档解释了坐标转换的原因。

另外,设备可以支持焦点。 您使用focusPointOfInterestSupportedtesting支持。 如果支持,则使用focusPointOfInterest设置焦点。 您传递一个CGPoint,其中{0,0}代表图片区域的左上angular,{1,1}代表右侧的Homebutton在横向模式下的右下angular,即使设备处于纵向模式。

在我的示例中,我一直使用.ContinuousAutoFocus.AutoFocus ,但文档指出.AutoFocus是正确的select。 奇怪的文件没有提及.AutoExpose ,但我在我的代码中使用它,它工作正常。

我还修改了我的示例代码,以包含.focusPointOfInterestSupported.exposurePointOfInterestSupportedtesting – 文档中还提到使用isFocusModeSupported:isExposureModeSupported:方法对于给定的焦点/曝光模式,在设置之前testing它是否在给定设备上可用,但是我假设设备是否支持兴趣点模式,那么它也支持自动模式。 这一切似乎在我的应用程序工作正常。

  device.focusPointOfInterest = focusPoint device.focusMode = AVCaptureFocusMode.AutoFocus device.exposurePointOfInterest = focusPoint device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure 

我不这样做为什么这样做,但它做到了。

设定焦点的更好方法是:

  • 首先计算兴趣点:

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

Swift 3.0解决scheme

将Cody的答案转换成Swift 3的工作解决scheme。

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

您必须按正确的顺序调用方法:

 if(device.lockForConfiguration(nil)) { device.focusPointOfInterest = CGPointMake(focus_x, focus_y) device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure device.unlockForConfiguration() } 

在设置焦点模式之前设置兴趣点,否则焦点将在前一个兴趣点上进行。

这同样适用于exposurePointOfInterest