2015-01-22 19 views
11

Ho utilizzato questo codice per ottenere Tap-to-Focus nell'app per telecamera personalizzata iOS, ma non funziona. Ecco il codiceToccare iOS per mettere a fuoco

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

Che dire non funziona? Quali errori vengono prodotti? Qual è il comportamento previsto? Qual è il comportamento reale? –

+0

tocco in un punto. e la messa a fuoco dovrebbe essere a quel punto. ma non c'è alcun effetto. non si sta concentrando su quel punto. invece è sempre nella messa a fuoco all'infinito. Questo è il problema. @ David – Krishna

+0

Avete camminato attraverso di esso per assicurare se entrambi sono presi? –

risposta

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

non lo faccio perché questo funziona, ma lo ha fatto.

14

Con un videoView: UIView visualizzazione del video e cameraDevice: AVCaptureDevice, il seguente sembra funzionare per me:

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

Nota che ho dovuto scambiare le x e y coordinate, e rimappare il x coord 1-0 invece di 0 a 1 - non sono sicuro del motivo, ma sembra che sia necessario farlo funzionare correttamente (anche se è un po 'complicato testarlo).

Modifica: Apple's documentation spiega il motivo della trasformazione delle coordinate.

Inoltre, un dispositivo può supportare un punto AF di interesse. Testare il supporto utilizzando focusPointOfInterestSupported. Se è supportato, si imposta il punto focale usando focusPointOfInterest. Si passa un CGPoint dove {0,0} rappresenta la parte in alto a sinistra dell'area dell'immagine e {1,1} rappresenta la parte in basso a destra in modalità orizzontale con il pulsante home sulla destra: questo si applica anche se il dispositivo è in modalità verticale .

Nel mio esempio avevo usato .ContinuousAutoFocus e .ContinuousAutoExposure, ma la documentazione indica .AutoFocus è la scelta giusta. Stranamente la documentazione non fa menzione di .AutoExpose, ma la sto usando nel mio codice e funziona perfettamente.

ho anche modificato il mio codice di esempio per includere .focusPointOfInterestSupported e .exposurePointOfInterestSupported test - la documentazione menziona anche utilizzando i metodi isFocusModeSupported: e isExposureModeSupported: per una data modalità di messa a fuoco/esposizione per verificare se è disponibile su un dato dispositivo prima di esso, ma io supponiamo che il dispositivo supporti le modalità punto di interesse, quindi supporta anche le modalità automatiche. Tutto sembra funzionare bene nella mia app.

+0

device.focusMode = AVCptureFocusMode.ContinuousAutoExposure è errato. Dovrebbe essere "ContinuousAutoFocus" –

+0

Oops, grazie! E anche due errori di ortografia! – Cody

+1

Ancora più semplice, è possibile utilizzare captureDevicePointOfInterestForPoint se si utilizza una classe AVCaptureVideoPreviewLayer – Crashalot

0

dovete chiamare i metodi nel giusto ordine:

if(device.lockForConfiguration(nil)) { 

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

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

impostare il punto di interesse prima di impostare la messa a fuoco il resto l'attenzione sarà fatta sulla precedente punto di interesse.

Lo stesso vale per exposurePointOfInterest.

3

Il modo migliore per impostare punto focale di interesse:

  • prima calcolare il punto di interesse:

    let devicePoint: CGPoint = (self.previewView.layer as! AVCaptureVideoPreviewLayer).captureDevicePointOfInterestForPoint(gestureRecognizer.locationInView(gestureRecognizer.view)) 
    
  • dopo che impostare il punto focale di interesse:

    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 Soluzione

fabbricato di risposta di Cody in una soluzione di lavoro con 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 
     } 
    } 
} 
Problemi correlati