12

ビュー内のコンテンツが変更されたときにフォーカスが失われた後、特定の POI での「タップしてフォーカス」状態から「オート フォーカス」状態に自動的に戻る切り替えを処理するにはどうすればよいですか? 標準のカメラ アプリまたは UIImagePickerController でフォーカスの動作に気付いた場合は、フォーカスのある領域をタップして電話を離した後、カメラが自動的に画面中央の連続オート フォーカスに切り替わることがあります。

UIImagePickerController が提供できるものよりも柔軟性が必要なので、最初に AVFoundation を使用して UIImagePickerController の動作を模倣する必要があります...

4

2 に答える 2

14

これは最初は非常に複雑に思えます...しかし、非常にシンプルになりました.Appleはすでに私たちのために99%の仕事をしてくれました. 「 subjectAreaChangeMonitoringEnabled 」をオンに設定し、「AVCaptureDeviceSubjectAreaDidChangeNotification」に KVO を登録するだけです。iOS 6.1 のドキュメント:

このプロパティの値は、照明の変化、大幅な動きなど、ビデオのサブジェクト領域の変化を受信機が監視する必要があるかどうかを示します。サブジェクト エリアの変更監視が有効になっている場合、キャプチャ デバイス オブジェクトは、サブジェクト エリアの変更を検出するたびに AVCaptureDeviceSubjectAreaDidChangeNotification を送信します。この時点で、関心のあるクライアントは、再フォーカス、露出、ホワイト バランスの調整などを希望する場合があります。

このプロパティの値を変更する前に、lockForConfiguration: を呼び出して、デバイスの構成プロパティへの排他的アクセスを取得する必要があります。そうしないと、このプロパティの値を設定すると例外が発生します。デバイスの構成が完了したら、unlockForConfiguration を呼び出してロックを解除し、他のデバイスが設定を構成できるようにします。

キー値観察を使用して、このプロパティの値の変化を観察できます。

(さらに良いことに、多くのコーナー ケースを処理する必要はありません。デバイスが POI で「フォーカスの調整」の最中にあり、コンテンツが変更された場合はどうなるでしょうか?デバイスが中央でオート フォーカスにフォールバックするのは望ましくありません。 、フォーカスアクションを終了させたい.「エリア変更通知」は、フォーカスが完了した後にのみトリガーされます.)

私のプロジェクトのサンプル コード スニペット。(構造は、公式の 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;
}
于 2013-05-30T18:34:24.063 に答える