繁体   English   中英

当摄像机视图中的内容发生变化时,“点按以对焦”至“自动对焦”。 像在相机应用程序或iOS的UIImagePickerController中的逻辑?

[英]“Tap to focus” to “auto focus” when content in camera view changed. Logic like in the stock Camera app or the UIImagePickerController for iOS?

当视图中的内容发生变化时,如何在失去焦点后自动处理从特定POI的“点击到焦点”切换回“自动对焦”状态? 如果您注意到相机应用程序或UIImagePickerController中的焦点行为,在您轻触一些区域并移动手机后,相机可以自动切换到屏幕中央的连续自动对焦。

我需要比UIImagePickerController可以提供的更多的灵活性,所以我需要首先使用AVFoundation来模仿UIImagePickerController行为......

这对我来说听起来非常复杂......但它变得非常简单,Apple已经为我们完成了99%的工作。 您需要做的就是设置“ subjectAreaChangeMonitoringEnabled ”并在“AVCaptureDeviceSubjectAreaDidChangeNotification”上注册KVO! 在iOS 6.1文档中:

此属性的值指示接收器是否应监视视频主题区域的更改,例如照明更改,实质移动等。 如果启用了主题区域更改监视,则捕获设备对象会在检测到主题区域发生更改时发送AVCaptureDeviceSubjectAreaDidChangeNotification,此时感兴趣的客户端可能希望重新聚焦,调整曝光,白平衡等。

在更改此属性的值之前,必须调用lockForConfiguration:以获取对设备配置属性的独占访问权。 如果不这样做,则设置此属性的值会引发异常。 完成配置设备后,请调用unlockForConfiguration以释放锁定并允许其他设备配置设置。

您可以使用键值观察来观察对此属性值的更改。

(更好的是,您不需要处理许多角落情况。如果设备处于POI的“adjustFocus”中间并且内容发生变化怎么办?您不希望设备回落到中心自动对焦,并希望焦点操作完成。“区域确实更改通知”仅在焦点完成后触发。)

我项目中的一些示例代码段。 (该结构遵循官方AVFoundation示例AVCam,因此您可以轻松地将它们放入并试用):

// CameraCaptureManager.m

@property (nonatomic, strong) AVCaptureDevice *backFacingCamera;

- (id) init{
    self = [super init];
    if (self){

        // TODO: more of your setup code for AVFoundation capture session
        for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
            if (device.position == AVCaptureDevicePositionBack){
                self.backFacingCamera = device;
            }
        }

        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

        void (^subjectAreaDidChangeBlock)(NSNotification *) = ^(NSNotification *notification) {

            if (self.videoInput.device.focusMode == AVCaptureFocusModeLocked ){
                // All you need to do is set the continuous focus at the center. This is the same behavior as
                // in the stock Camera app
                [self continuousFocusAtPoint:CGPointMake(.5f, .5f)];
            }
        };

        self.subjectAreaDidChangeObserver = [notificationCenter addObserverForName:AVCaptureDeviceSubjectAreaDidChangeNotification
                                                                            object:nil
                                                                             queue:nil
                                                                        usingBlock:subjectAreaDidChangeBlock];

        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        [self addObserver:self forKeyPath:keyPathAdjustingFocus options:NSKeyValueObservingOptionNew context:NULL];
    }

    return self;
}

-(void) dealloc{
    // Remove the observer when done
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self.deviceOrientationDidChangeObserver];
}

- (BOOL) setupSession{
    BOOL sucess = NO;

    if ([self.backFacingCamera lockForConfiguration:nil]){
        // Turn on subject area change monitoring
        self.backFacingCamera.subjectAreaChangeMonitoringEnabled = YES;
    }

    [self.backFacingCamera unlockForConfiguration];

    // TODO: Setup add input etc...

    return sucess;
}

我刚看到@Xiaochao Yang的答案的评论,我想补充一些代码CGPointMake(.5f, .5f) 根据Apple的API,您设置到摄像机的CGPoint在{0,0}到{1,1}的范围内,同时CGPointMake(.5f, .5f)表示摄像机的中心。

此属性表示CGPoint,其中{0,0}对应于图片区域的左上角,{1,1}对应于横向模式的右下角,右侧的主页按钮 - 即使设备是在纵向模式下

来自AVCaptureDevice类参考

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM