open ios camera avfoundation

open - ios AVFoundation toca para enfocar



open camera swift 4 (2)

Intento crear una aplicación de cámara que, más o menos, actúe como la aplicación de cámara predeterminada. Lo que no funciona para mí en este momento, es tocar para enfocar. Quiero que la cámara enfoque y haga lo que haga en mi punto tocado, tal como lo hace la aplicación real de la cámara.

Aquí está mi 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]; };

Y aquí está el método que debería hacer que mi cámara enfocara todo al hacer clic.

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

Nada realmente sucede una vez que hago clic en la pantalla.


Tienes que ajustar el touchPoint a un rango de [0,1] usando algo como el siguiente código:

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

La documentación sobre esto se puede encontrar en Apple - Pautas de programación AV Foundation - ver la sección Captura de medios, donde encontrará información sobre los modos de enfoque :

Si es compatible, establezca el punto focal utilizando focusPointOfInterest. Usted pasa un CGPoint donde {0,0} representa la parte superior izquierda del área de la imagen, y {1,1} representa la parte inferior derecha en el modo horizontal con el botón de inicio a la derecha, esto se aplica incluso si el dispositivo está en modo vertical .


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

y luego esto:

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

Una versión Swift:

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