[英]ios AVFoundation tap to focus
我正在嘗試創建一個相機應用程序,它或多或少會像默認的相機應用程序。 目前對我不起作用的東西是重點關注。 我希望相機能夠對焦並在觸摸點上做任何事情,就像真正的相機應用程序一樣。
這是我的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];
};
這里的方法應該讓我的相機專注於點擊。
-(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);
}];
}
點擊屏幕后沒有任何事情發生。
您必須使用類似下面的代碼將touchPoint調整到[0,1]的范圍:
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];
有關這方面的文檔可以在Apple - AV Foundation Programming Guidelines中找到 - 請參閱Media Capture部分,您可以在其中找到有關聚焦模式的信息 :
如果支持,則使用focusPointOfInterest設置焦點。 您傳遞一個CGPoint,其中{0,0}表示圖片區域的左上角,{1,1}表示橫向模式的右下角,右側的主頁按鈕 - 即使設備處於縱向模式,這也適用。
UITapGestureRecognizer *shortTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapToFocus:)];
shortTap.numberOfTapsRequired=1;
shortTap.numberOfTouchesRequired=1;
[viewCanvasRecording addGestureRecognizer:shortTap];
然后這個:
- (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版本:
@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)
}
}
}
}
這就是我如何處理AV相機預覽的手勢。 首先設置您的UITapGestureRecognizer,然后使用captureDevicePointOfInterestForPoint獲取該點。
- (void)setupGestures
{
UITapGestureRecognizer *tapToFocusRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleTapToFocusAndExposureRecognizer:)];
[self addGestureRecognizer:tapToFocusRecognizer];
}
- (void)handleTapToFocusAndExposureRecognizer:(UITapGestureRecognizer*)tabRecognizer {
CGPoint touchPoint = [tabRecognizer locationInView:self];
CGPoint point = [self.previewLayer captureDevicePointOfInterestForPoint:touchPoint];
AVCaptureDevice *device = [self.videoCaptureDeviceInput device];
NSError *error = nil;
if (tabRecognizer.state == UIGestureRecognizerStateEnded) {
if (![device lockForConfiguration:&error]) {
if (error) {
RCTLogError(@"%s: %@", __func__, error);
}
return;
}
[device setFocusPointOfInterest:CGPointMake(point.x, point.y)];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device setExposurePointOfInterest:CGPointMake(point.x, point.y)];
[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
[device unlockForConfiguration];
}
}
我正在使用AVCaptureVideoPreviewLayer獲取觸摸點。 但是如果你使用GLKView來渲染預覽而不是AVCaptureVideoPreviewLayer,你就無法直接得到這一點,但必須像以前的答案那樣得到點。
ios開發的新編碼器。 希望這可以提供幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.