2012-10-26 3 views
22

Ich versuche, eine Kamera-App zu erstellen, die mehr oder weniger wie die Standard-Kamera-App fungieren würde. Das Ding, das im Moment für mich nicht funktioniert, ist Tippen auf den Fokus. Ich möchte, dass sich die Kamera fokussiert und alles tut, was sie an meinem berührten Punkt tut, genau wie die echte Kamera-App.ios AVFoundation tippen, um zu fokussieren

Hier ist mein viewDidLoad

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Session 
    _session = [[AVCaptureSession alloc] init]; 
    _session.sessionPreset = AVCaptureSessionPresetPhoto; 

    // Input 
    _videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    _videoInput = [AVCaptureDeviceInput deviceInputWithDevice:_videoDevice error:nil]; 

    // Output 
    _frameOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    _frameOutput.videoSettings = [NSDictionary dictionaryWithObject:AVVideoCodecJPEG forKey:AVVideoCodecKey]; 

    [_frameOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 
    [_session addInput:_videoInput]; 
    [_session addOutput:_frameOutput]; 
    [_session startRunning]; 
}; 

Und hier ist die Methode, die meine Kamera Fokus Sachen auf Klick machen sollte.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    [touches enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { 
     UITouch *touch = obj; 
     CGPoint touchPoint = [touch locationInView:touch.view]; 
     focusLayer.frame = CGRectMake((touchPoint.x-25), (touchPoint.y-25), 50, 50); 

     if ([_videoDevice isFocusPointOfInterestSupported]) { 
      NSError *error; 
      if ([_videoDevice lockForConfiguration:&error]) { 
       [_videoDevice setFocusPointOfInterest:touchPoint]; 
       [_videoDevice setExposurePointOfInterest:touchPoint]; 

       [_videoDevice setFocusMode:AVCaptureFocusModeAutoFocus]; 
       if ([_videoDevice isExposureModeSupported:AVCaptureExposureModeAutoExpose]){ 
        [_videoDevice setExposureMode:AVCaptureExposureModeAutoExpose]; 
       } 
       [_videoDevice unlockForConfiguration]; 
      } 
     } 


     // NSLog(@"x = %f, y = %f", touchPoint.x, touchPoint.y); 
    }]; 
} 

Nichts passiert wirklich, sobald ich auf den Bildschirm klicke.

Antwort

31

Sie haben die Berührungspunkts auf einen Bereich von [0,1] mit so etwas wie dem folgenden Code einstellen:

CGRect screenRect = [[UIScreen mainScreen] bounds]; 
    screenWidth = screenRect.size.width; 
    screenHeight = screenRect.size.height; 
    double focus_x = thisFocusPoint.center.x/screenWidth; 
    double focus_y = thisFocusPoint.center.y/screenHeight; 

    [[self captureManager].videoDevice lockForConfiguration:&error]; 
    [[self captureManager].videoDevice setFocusPointOfInterest:CGPointMake(focus_x,focus_y)]; 
    [[self captureManager].videoDevice unlockForConfiguration]; 

Die Dokumentation dazu finden Sie in Apple - AV Foundation Programming Guidelines - see section Media Capture where you will find information on Focus Modes finden:

Wenn Es wird unterstützt, Sie legen 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 .

+0

Gibt es eine Dokumentation oder etwas, das erklärt, warum dies so gemacht werden muss? – spacecash21

+0

Die Antwort wurde aktualisiert, um auf die Dokumentation von Apple zu verweisen. –

+19

Sie können auch 'AVCaptureVideoPreviewLayer' verwenden und es ist' captureDevicePointOfInterestForPoint' Methode, um den Fokuspunkt zu berechnen. – Legoless

6
UITapGestureRecognizer *shortTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapToFocus:)]; 
shortTap.numberOfTapsRequired=1; 
shortTap.numberOfTouchesRequired=1; 
[viewCanvasRecording addGestureRecognizer:shortTap]; 

und dann das:

- (void)handleTapToFocus:(UITapGestureRecognizer *)tapGesture 
{ 
    AVCaptureDevice *acd=!currentFrontCamera ? captureBackInput.device : captureFrontInput.device; 

    if (tapGesture.state == UIGestureRecognizerStateEnded) 
    { 
     CGPoint thisFocusPoint = [tapGesture locationInView:viewCanvasRecording]; 

     double focus_x = thisFocusPoint.x/viewCanvasRecording.frame.size.width; 
     double focus_y = thisFocusPoint.y/viewCanvasRecording.frame.size.height; 

     if ([acd isFocusModeSupported:AVCaptureFocusModeAutoFocus] && [acd isFocusPointOfInterestSupported]) 
     { 
      if ([acd lockForConfiguration:nil]) 
      { 
       [acd setFocusMode:AVCaptureFocusModeAutoFocus]; 
       [acd setFocusPointOfInterest:CGPointMake(focus_x, focus_y)]; 

       /* 
       if ([acd isExposureModeSupported:AVCaptureExposureModeAutoExpose] && [acd isExposurePointOfInterestSupported]) 
       { 
        [acd setExposureMode:AVCaptureExposureModeAutoExpose]; 
        [acd setExposurePointOfInterest:CGPointMake(focus_x, focus_y)]; 
       }*/ 

       [acd unlockForConfiguration]; 
      } 
     } 
    } 
} 

A Swift Version:

@IBAction func tapToFocus(_ sender: UITapGestureRecognizer) { 
    if (sender.state == .ended) { 
     let thisFocusPoint = sender.location(in: previewView) 

     print("touch to focus ", thisFocusPoint) 

     let focus_x = thisFocusPoint.x/previewView.frame.size.width 
     let focus_y = thisFocusPoint.y/previewView.frame.size.height 

     if (captureDevice!.isFocusModeSupported(.autoFocus) && captureDevice!.isFocusPointOfInterestSupported) { 
      do { 
       try captureDevice?.lockForConfiguration() 
       captureDevice?.focusMode = .autoFocus 
       captureDevice?.focusPointOfInterest = CGPoint(x: focus_x, y: focus_y) 

       if (captureDevice!.isExposureModeSupported(.autoExpose) && captureDevice!.isExposurePointOfInterestSupported) { 
        captureDevice?.exposureMode = .autoExpose; 
        captureDevice?.exposurePointOfInterest = CGPoint(x: focus_x, y: focus_y); 
       } 

       captureDevice?.unlockForConfiguration() 
      } catch { 
       print(error) 
      } 
     } 
    } 
} 
+0

für 'focus_x' und' focus_y' warum teilen Sie durch 'width' und' height'? – Crashalot

+0

Ah, lesen Sie dies nur aus der Apple-Dokumentation: 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 . – Crashalot