iOS自動對焦拍照

最新有拍照的需求是這樣的 ~
IMG2022124-152840.png
03.gif
  • 手動點擊屏幕聚焦,聚焦完成之后就自動拍照

  • 于是開始各種腦補,在別人的基本拍照框架上進行改造 ~

  • 使用了LGPhotoBrowser

  • 使用了MLPhotoBrowser

據說IOS 6開放了相機的自動對焦API,看到這里我就覺得穩了

表情01.gif
//更改設備屬性前一定要鎖上
-(void)changeDevicePropertySafety:(void (^)(AVCaptureDevice *captureDevice))propertyChange{
    //也可以直接用_videoDevice,但是下面這種更好
    AVCaptureDevice *captureDevice= [_input device];
    //AVCaptureDevice *captureDevice= self.device;
    NSError *error;
    //注意改變設備屬性前一定要首先調用lockForConfiguration:調用完之后使用unlockForConfiguration方法解鎖,意義是---進行修改期間,先鎖定,防止多處同時修改
    BOOL lockAcquired = [captureDevice lockForConfiguration:&error];
    if (!lockAcquired) {
        NSLog(@"鎖定設備過程error,錯誤信息:%@",error.localizedDescription);
    }else{
        [_session beginConfiguration];
        propertyChange(captureDevice);
        [captureDevice unlockForConfiguration];
        [_session commitConfiguration];
    }
}

// 點擊屏幕,觸發聚焦
- (void)cameraDidSelected:(ZLCameraView *)camera{

    // 當設置完成之后,需要回調到上面那個方法??
    [self changeDevicePropertySafety:^(AVCaptureDevice *captureDevice) {
        
        // 觸摸屏幕的坐標點需要轉換成0-1,設置聚焦點
        CGPoint cameraPoint= [self.preview captureDevicePointOfInterestForPoint:camera.point];
        
        /*****必須先設定聚焦位置,在設定聚焦方式******/
        //聚焦點的位置
        if ([self.device isFocusPointOfInterestSupported]) {
            [self.device setFocusPointOfInterest:cameraPoint];
        }
        
        // 聚焦模式
        if ([self.device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
            [self.device setFocusMode:AVCaptureFocusModeAutoFocus];
        }else{
            NSLog(@"聚焦模式修改失敗");
        }

        //曝光點的位置
        if ([self.device isExposurePointOfInterestSupported]) {
            [self.device setExposurePointOfInterest:cameraPoint];
        }
        
        //曝光模式
        if ([self.device isExposureModeSupported:AVCaptureExposureModeAutoExpose]) {
            [self.device setExposureMode:AVCaptureExposureModeAutoExpose];
        }else{
            NSLog(@"曝光模式修改失敗");
        }
        
        // 防止點擊一次,多次聚焦,會連續拍多張照片
        self.canTakePicture = YES;
        
    }];
    
}

聚焦完成了,那么就是拍照了

于是又是各種問,各種 ??,發現蘋果沒有提供對焦成功的事件,但是提供了對焦發生改變的屬性那么,是可以監聽這個屬性 adjustingFocus

表情02.jpg
// 監聽焦距發生改變
-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context {

    if([keyPath isEqualToString:@"adjustingFocus"]){
        BOOL adjustingFocus =[[change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:1]];
        
        NSLog(@"adjustingFocus~~%d  change~~%@", adjustingFocus, change);
        // 0代表焦距不發生改變 1代表焦距改變
        if (adjustingFocus == 0) {
                        
        }

    }
}

// 增加監聽
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
    AVCaptureDevice *camDevice =[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    int flags =NSKeyValueObservingOptionNew;
    [camDevice addObserver:self forKeyPath:@"adjustingFocus" options:flags context:nil];
}
// 移除監聽
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
 
    AVCaptureDevice*camDevice =[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    [camDevice removeObserver:self forKeyPath:@"adjustingFocus"];
}

問題來了,焦距發生改變,不一定最清楚的

表情03.jpg
屏幕快照 2016-12-31 上午10.41.14.png

后來發現adjustingFocus的值為0的時候(聚焦沒有改變)

聚焦基本是完成。并且還有時候,聚焦一次(adjustingFocus會有兩次打印 1:聚焦發生改變 0:聚焦沒有改變),有的時候會聚焦兩次(adjustingFocus會有四次打印 1 0 1 0)。這兩種方式都是最后的0處有較清楚的圖片
于是我增加了延時,讓每次拍照,都能保證在最后的adjustingFocus = 0的地方,我測試都可以得到較清楚的照片,現在只能先這樣了 ~ 有更好的方式記得@me

表情04.jpg
// 監聽焦距發生改變
-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context {

    if([keyPath isEqualToString:@"adjustingFocus"]){
        BOOL adjustingFocus =[[change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:1]];
        
        NSLog(@"adjustingFocus~~%d  change~~%@", adjustingFocus, change);
        // 0代表焦距不發生改變 1代表焦距改變
        if (adjustingFocus == 0) {
            
            // 判斷圖片的限制個數
            if ((self.images.count == 1 && self.cameraType == ZLCameraSingle) || !self.GraphRecognition || !self.canTakePicture) {
                return;
            }
            
            // 點擊一次可能會聚一次焦,也有可能會聚兩次焦。一次聚焦,圖像清晰。如果聚兩次焦,照片會在第二次沒有聚焦完成拍照,應為第一次聚焦完成會觸發拍照,而拍照時間在第二次未聚焦完成,圖像不清晰。增加延時可以讓每次都是聚焦完成的時間點
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                [NSThread sleepForTimeInterval:0.2];
                dispatch_sync(dispatch_get_main_queue(), ^{
                    // 拍照
                    [self stillImage:nil];
                });
            });
        }

    }
}

最后附上代碼 ~ demo下了好久了,來不及找到在哪里下的 ~ 如有知道,@我,我會第一時間注明出處 下載

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容