我正在尝试创建一个相机应用程序,它或多或少会像默认的相机应用程序一样。 目前对我不起作用的东西是重点关注。我希望相机能够对焦并在触摸点上做任何事情,就像真正的相机应用程序一样。
这是我的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);
}];
}
点击屏幕后没有任何事情发生。
答案 0 :(得分:33)
您必须使用以下代码调整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];
中找到
如果支持,则使用focusPointOfInterest设置焦点。您传递一个CGPoint,其中{0,0}表示图片区域的左上角,{1,1}表示横向模式的右下角,右侧的主页按钮 - 即使设备处于纵向模式,这也适用
答案 1 :(得分:6)
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)
}
}
}
}
答案 2 :(得分:1)
所以这就是我如何处理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开发的新编码器。希望这可以提供帮助。