2013-04-05 12 views
8

Sto clonando l'app per fotocamera di Apple utilizzando AVCaptureSession basata sull'app dell'app AppCam di Apple. Il problema è che non riesco a vedere il rettangolo di messa a fuoco nella schermata di anteprima del video. Ho usato il seguente codice per l'impostazione dello stato attivo, ma il rettangolo di messa a fuoco non è ancora mostrato.iphone camera show focus rettangle

AVCaptureDevice *device = [[self videoInput] device]; 
if ([device isFocusModeSupported:focusMode] && [device focusMode] != focusMode) { 
    NSError *error; 

     printf(" setFocusMode \n"); 
    if ([device lockForConfiguration:&error]) { 
     [device setFocusMode:focusMode]; 
     [device unlockForConfiguration]; 
    } else { 
     id delegate = [self delegate]; 
     if ([delegate respondsToSelector:@selector(acquiringDeviceLockFailedWithError:)]) { 
      [delegate acquiringDeviceLockFailedWithError:error]; 
     } 
    }  
} 

Quando uso UIImagePickerController, messa a fuoco automatica, toccare messa a fuoco sono supportati di default, e può vedere messa a fuoco rettangolo. Non c'è modo di mostrare il rettangolo di messa a fuoco nel livello di anteprima del video usando AVCaptureSession?

+0

hmm, sembra che nessuno sa Thi S. – ttotto

risposta

11

L'animazione di messa a fuoco è un'animazione personalizzata completa che devi creare da sola. Attualmente sto avendo lo stesso problema come te: Voglio mostrare un rettangolo come feedback per l'utente dopo aver toccato il livello di anteprima.

La prima cosa che voglio fare è attuare l'attenzione tap-to-, probabilmente dove si avvia lo strato di anteprima:

UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToFocus:)]; 
[tapGR setNumberOfTapsRequired:1]; 
[tapGR setNumberOfTouchesRequired:1]; 
[self.captureVideoPreviewView addGestureRecognizer:tapGR]; 

ora implementare il metodo tap-to-focus stesso:

-(void)tapToFocus:(UITapGestureRecognizer *)singleTap{ 
    CGPoint touchPoint = [singleTap locationInView:self.captureVideoPreviewView]; 
    CGPoint convertedPoint = [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:touchPoint]; 
    AVCaptureDevice *currentDevice = currentInput.device; 

    if([currentDevice isFocusPointOfInterestSupported] && [currentDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]){ 
     NSError *error = nil; 
     [currentDevice lockForConfiguration:&error]; 
     if(!error){ 
      [currentDevice setFocusPointOfInterest:convertedPoint]; 
      [currentDevice setFocusMode:AVCaptureFocusModeAutoFocus]; 
      [currentDevice unlockForConfiguration]; 
     }  
    } 
} 

L'ultima cosa, che non ho ancora implementato da solo, consiste nell'aggiungere l'animazione di messa a fuoco sul livello di anteprima o piuttosto sul controller di visualizzazione che regge il livello di anteprima. Credo che si possa fare in tapToFocus :. Lì hai già il punto di contatto. Basta aggiungere una vista di immagini animate o un'altra vista che ha la posizione di tocco come centro. Al termine dell'animazione, rimuovi la visualizzazione dell'immagine.

+1

Puoi anche dare un'occhiata a: http://stackoverflow.com/questions/15449271/avfoundation-tap-to-focus-feedback-rectangle C'è una buona descrizione su come implementare l'animazione di messa a fuoco con un UIView – xxtesaxx

2

Swift implementazione

Gesto:

private func focusGesture() -> UITapGestureRecognizer { 

    let tapRec: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(kTapToFocus)) 
    tapRec.cancelsTouchesInView = false 
    tapRec.numberOfTapsRequired = 1 
    tapRec.numberOfTouchesRequired = 1 

    return tapRec 
} 

Azione:

private func tapToFocus(gesture : UITapGestureRecognizer) { 

    let touchPoint:CGPoint = gesture.locationInView(self.previewView) 
    let convertedPoint:CGPoint = previewLayer!.captureDevicePointOfInterestForPoint(touchPoint) 

    let currentDevice:AVCaptureDevice = videoDeviceInput!.device 

    if currentDevice.focusPointOfInterestSupported && currentDevice.isFocusModeSupported(AVCaptureFocusMode.AutoFocus){ 
     do { 
      try currentDevice.lockForConfiguration() 
      currentDevice.focusPointOfInterest = convertedPoint 
      currentDevice.focusMode = AVCaptureFocusMode.AutoFocus 
      currentDevice.unlockForConfiguration() 
     } catch { 

     } 
    } 

} 
0

implementazione swift3

lazy var focusGesture: UITapGestureRecognizer = { 
    let instance = UITapGestureRecognizer(target: self, action: #selector(tapToFocus(_:))) 
    instance.cancelsTouchesInView = false 
    instance.numberOfTapsRequired = 1 
    instance.numberOfTouchesRequired = 1 
    return instance 
}() 

func tapToFocus(_ gesture: UITapGestureRecognizer) { 
    guard let previewLayer = previewLayer else { 
     print("Expected a previewLayer") 
     return 
    } 
    guard let device = device else { 
     print("Expected a device") 
     return 
    } 

    let touchPoint: CGPoint = gesture.location(in: cameraView) 
    let convertedPoint: CGPoint = previewLayer.captureDevicePointOfInterest(for: touchPoint) 
    if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(AVCaptureFocusMode.autoFocus) { 
     do { 
      try device.lockForConfiguration() 
      device.focusPointOfInterest = convertedPoint 
      device.focusMode = AVCaptureFocusMode.autoFocus 
      device.unlockForConfiguration() 
     } catch { 
      print("unable to focus") 
     } 
    } 
}