2015-01-22 18 views
11

Ich habe diesen Code verwendet, um Tap-to-Focus in iOS benutzerdefinierte Kamera-App zu erreichen, aber es funktioniert nicht. Hier ist der CodeiOS tippen zum Fokussieren

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

Was ist es nicht funktioniert? Welche Fehler werden erzeugt? Was ist das erwartete Verhalten? Was ist das tatsächliche Verhalten? –

+0

Ich berühre einen Punkt. und Fokus sollte an diesem Punkt sein. aber es gibt keinen Effekt. Es konzentriert sich nicht auf diesen Punkt. stattdessen ist es immer im Unendlichkeitsfokus. Das ist das Problem. @David – Krishna

+0

Haben Sie es durchlaufen, um sicherzustellen, dass beide Wenns genommen werden? –

Antwort

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

Ich weiß nicht, warum das funktioniert, aber es tat.

14

Mit einem videoView: UIView das Video angezeigt wird, und cameraDevice: AVCaptureDevice scheint folgende für mich zu arbeiten:

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

Bitte beachte, dass ich die x und y Koordinaten tauschen musste, und Neuzuordnung den x coord von 1 auf 0 anstelle von 0 bis 1 - nicht sicher, warum das der Fall sein sollte, aber es scheint notwendig zu sein, damit es richtig funktioniert (obwohl es ein wenig schwierig ist, es zu testen).

Bearbeiten: Apple's documentation erläutert den Grund für die Koordinatentransformation.

Zusätzlich kann ein Gerät einen Fokuspunkt von Interesse unterstützen. Sie testen mithilfe von focusPointOfInterestSupported auf Unterstützung. Wenn es unterstützt wird, legen Sie den Fokuspunkt mit FocusPointOfInterest fest. Sie übergeben einen CGPoint, wobei {0,0} links oben im Bildbereich steht und {1,1} im Querformat mit der rechten Home-Taste die untere rechte Ecke darstellt. Dies gilt auch, wenn sich das Gerät im Hochformat befindet .

In meinem Beispiel, das ich hatte mit .ContinuousAutoFocus und .ContinuousAutoExposure, aber die Dokumentation zeigt .AutoFocus die richtige Wahl ist. Seltsamerweise erwähnt die Dokumentation .AutoExpose nicht, aber ich benutze es in meinem Code und es funktioniert gut.

I modifiziert auch mein Beispielcode .focusPointOfInterestSupported und .exposurePointOfInterestSupported Tests umfassen - die Dokumentation erwähnt auch die isFocusModeSupported: und isExposureModeSupported: Methoden für einen bestimmten Fokus/Belichtungs-Modus zu testen, ob es auf einem bestimmten Gerät es vor der Einstellung vorhanden ist, aber ich Angenommen, das Gerät unterstützt die Point-of-Interest-Modi, dann unterstützt es auch die Auto-Modi. Alles scheint in meiner App gut zu funktionieren.

+0

device.focusMode = AVCptureFocusMode.ContinuousAutoExposure ist falsch. Sollte "ContinuousAutoFocus" sein –

+0

Ups, danke! Und zwei Rechtschreibfehler auch! – Cody

+1

Noch einfacher können Sie captureDevicePointOfInterestForPoint verwenden, wenn Sie eine AVCaptureVideoPreviewLayer-Klasse verwenden – Crashalot

0

Sie haben die Methoden in der richtigen Reihenfolge zu nennen:

if(device.lockForConfiguration(nil)) { 

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

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

den Punkt von Interesse ein, bevor Sie den Fokusmodus sonst die Scharfeinstellung auf dem vorherigen Punkt von Interesse durchgeführt werden. Das gleiche gilt für exposurePointOfInterest.

3

Der bessere Weg Fokuspunkt von Interesse zu setzen:

  • zuerst den Punkt von Interesse berechnen:

    let devicePoint: CGPoint = (self.previewView.layer as! AVCaptureVideoPreviewLayer).captureDevicePointOfInterestForPoint(gestureRecognizer.locationInView(gestureRecognizer.view)) 
    
  • nach, dass der Schwerpunkt der Umgebung gesetzt:

    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

Schnell 3.0 Lösung

Converted Cody Antwort in einer Arbeitslösung mit 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 
     } 
    } 
} 
Verwandte Themen