2012-10-26 13 views
22

Próbuję utworzyć aplikację aparatu fotograficznego, która będzie działać mniej więcej tak samo jak domyślna aplikacja aparatu. Rzecz, która w tej chwili nie działa dla mnie, to dotknij, aby się skupić. Chcę, aby kamera skupiała się i robiła wszystko, co robi na moim dotkniętym punkcie, tak jak robi to prawdziwa aplikacja aparatu.ios AVFoundation stuknij, aby ustawić ostrość

Oto mój 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]; 
}; 

A oto metoda, która powinna uczynić mój aparat ostrości rzeczy na kliknięcia.

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

Nic tak naprawdę nie dzieje się po kliknięciu na ekranie.

Odpowiedz

31

Trzeba wyregulować styczności z zakresu [0,1] przy użyciu coś podobnego do następującego kodu:

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]; 

Dokumentacja na ten temat można znaleźć w Apple - AV Foundation Programming Guidelines - see section Media Capture where you will find information on Focus Modes:

If jest obsługiwany, ustawiasz punkt centralny za pomocą focusPointOfInterest. Możesz przekazać punkt CGPoint, w którym {0,0} oznacza lewą górną część obszaru obrazu, a {1,1} oznacza prawy dolny róg w trybie poziomym, a przycisk strony głównej po prawej stronie - dotyczy to również urządzenia w trybie portretu .

+0

Czy istnieje dokumentacja lub coś, co wyjaśnia, dlaczego należy to zrobić w ten sposób? – spacecash21

+0

Zaktualizowano odpowiedź, aby wskazać dokumentację dostarczoną przez Apple. –

+19

Można również użyć metody "AVCaptureVideoPreviewLayer" i metody "captureDevicePointOfInterestForPoint" do obliczenia punktu ostrości. – Legoless

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

a następnie to:

- (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]; 
      } 
     } 
    } 
} 

Swift wersja:

@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

dla 'focus_x' i' focus_y' dlaczego dzielisz przez 'width' i' height'? – Crashalot

+0

Ah, po prostu przeczytaj to z dokumentacji Apple: Ponadto urządzenie może obsługiwać punkt ostrości. Testujesz obsługę za pomocą focusPointOfInterestSupported. Jeśli jest obsługiwany, ustawiasz punkt ogniskowy za pomocą focusPointOfInterest. Możesz przekazać punkt CGPoint, w którym {0,0} oznacza lewą górną część obszaru obrazu, a {1,1} oznacza prawy dolny róg w trybie poziomym, a przycisk strony głównej po prawej stronie - dotyczy to również urządzenia w trybie portretu . – Crashalot

Powiązane problemy