最新有拍照的需求是這樣的 ~
IMG2022124-152840.png
03.gif
手動點擊屏幕聚焦,聚焦完成之后就自動拍照
于是開始各種腦補,在別人的基本拍照框架上進行改造 ~
據說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下了好久了,來不及找到在哪里下的 ~ 如有知道,@我,我會第一時間注明出處 下載