2015-01-22 4 views
11

Я использовал этот код для достижения Tap-to-Focus в приложении для камеры 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() 
     } 
    } 
} 
+1

Что об этом не работает? Какие ошибки возникают? Каково ожидаемое поведение? Каково фактическое поведение? –

+0

Я касаюсь точки. и в этот момент следует сосредоточиться. но нет никакого эффекта. он не фокусируется в этой точке. вместо этого он всегда находится в фокусе бесконечности. Это проблема. @David – Krishna

+0

Прошли ли вы через него, чтобы застраховать оба взятых? –

ответ

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

Я не знаю почему это работает, но это было сделано.

14

С 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 коорд от 1 до 0 вместо 0 до 1 - не уверен, почему это должно быть так, но, похоже, необходимо, чтобы он работал правильно (хотя и немного сложно проверить его).

Редактировать: Apple's documentation объясняет причину преобразования координат.

Кроме того, устройство может поддерживать точку фокусировки. Вы тестируете поддержку с помощью focusPointOfInterestSupported. Если он поддерживается, вы устанавливаете фокус с помощью focusPointOfInterest. Вы передаете CGPoint, где {0,0} представляет верхнюю левую часть области изображения, а {1,1} представляет нижний правый в альбомном режиме с кнопкой «домой» справа - это применяется, даже если устройство находится в портретном режиме ,

В моем примере я использовал .ContinuousAutoFocus и .ContinuousAutoExposure, но документация указывает .AutoFocus является правильным выбором. Как ни странно, в документации нет упоминания о .AutoExpose, но я использую его в своем коде, и он отлично работает.

Я также изменил мой пример кода для включения .focusPointOfInterestSupported и .exposurePointOfInterestSupported тесты - документация также упоминает, используя методы isFocusModeSupported: и isExposureModeSupported: для режима данного фокуса/экспозиции, чтобы проверить, является ли она доступна на данном устройстве перед установкой, но я предположим, что устройство поддерживает режимы интереса, а также поддерживает автоматические режимы. Кажется, все хорошо работает в моем приложении.

+0

device.focusMode = AVCptureFocusMode.ContinuousAutoЭффект неправильный. Должно быть «ContinuousAutoFocus» –

+0

Упс, спасибо! И две орфографические ошибки тоже! – Cody

+1

Еще проще, вы можете использовать captureDevicePointOfInterestForPoint, если вы используете класс AVCaptureVideoPreviewLayer – Crashalot

0

Вы должны вызвать методы в правильном порядке:

if(device.lockForConfiguration(nil)) { 

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

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

Установите точку интереса перед установкой режима фокусировки еще фокус будет сделан на предыдущей точке интереса.

То же самое относится к exposurePointOfInterest.

3

Лучший способ установить точку фокусировки интереса:

  • сначала вычислить точки интереса:

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

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