iOS 自定義相機(jī)自動(dòng)對(duì)焦拍照求助

最近在做一個(gè)自定義相機(jī)的Demo, Demo的需求是相機(jī)對(duì)著某一處,當(dāng)自動(dòng)對(duì)焦成功后,然后拍攝圖片。

- (void)initAVCaptureSession{
    
    self.session = [[AVCaptureSession alloc] init];
    NSError *error;
    self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    [self.device addObserver:self
                  forKeyPath:@"adjustingFocus"
                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                     context:nil];
    
    //更改這個(gè)設(shè)置的時(shí)候必須先鎖定設(shè)備,修改完后再解鎖,否則崩潰
    [self.device lockForConfiguration:nil];
    //設(shè)置閃光燈為自動(dòng)
    //    [device setFlashMode:AVCaptureFlashModeOff];//AVCaptureFlashModeAuto
    [self.device unlockForConfiguration];
    self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:self.device error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
    self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    //輸出設(shè)置。AVVideoCodecJPEG   輸出jpeg格式圖片
    NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
    [self.stillImageOutput setOutputSettings:outputSettings];
    if ([self.session canAddInput:self.videoInput]) {
        [self.session addInput:self.videoInput];
    }
    if ([self.session canAddOutput:self.stillImageOutput]) {
        [self.session addOutput:self.stillImageOutput];
    }
    self.session.sessionPreset = AVCaptureSessionPresetHigh;
    
    //初始化預(yù)覽圖層
    WEAKSELF
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        weakSelf.previewLayer.frame = CGRectMake(0, 0,kScreenWidth, kScreenHeight);
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.cameraView.layer.masksToBounds = YES;
            [weakSelf.cameraView.layer addSublayer:self.previewLayer];
        });
    });
}

自動(dòng)對(duì)焦的功能使用的是KVO實(shí)現(xiàn)的, 在上面的方法中添加了一個(gè)KVO:

[self.device addObserver:self
                  forKeyPath:@"adjustingFocus"
                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                     context:nil];

下面是自動(dòng)對(duì)焦KVO的方法:

-(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]];
        if (adjustingFocus == 0) {
            
            [timer setFireDate:[NSDate distantFuture]];//停止
            
            [self.device removeObserver:self forKeyPath:@"adjustingFocus"];
            AVCaptureConnection *stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
            UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];
            AVCaptureVideoOrientation avcaptureOrientation = [self avOrientationForDeviceOrientation:curDeviceOrientation];
            [stillImageConnection setVideoOrientation:avcaptureOrientation];
            [stillImageConnection setVideoScaleAndCropFactor:self.effectiveScale];
            WEAKSELF
            [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
                
                dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    if (!error) {
                        if (imageDataSampleBuffer == NULL) {
                            //沒有圖片
                            GPLog(@"當(dāng)前拍攝的圖片沒有數(shù)據(jù)!");
                        }
                        
                        NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                        ALAuthorizationStatus author = [ALAssetsLibrary authorizationStatus];
                        if (author == ALAuthorizationStatusRestricted || author == ALAuthorizationStatusDenied){
                            //無(wú)權(quán)限
                            [weakSelf showHUDText:@"沒有權(quán)限!"];
                            return;
                        }
                        UIImage *key_image = [UIImage imageWithData:jpegData];
                        if (!weakSelf.isPacket) {
                            weakSelf.cameraImg.hidden = NO;
                            weakSelf.cameraImg.image = [UIImage scaleImage:key_image WithSize:CGSizeMake(480, 480)];
                            weakSelf.cameraObj = key_image;
                            weakSelf.packetCannelBtn.hidden = NO;
                            weakSelf.packetHereBtn.hidden = NO;
                        } else {
                            NSURL *key_file = [NSURL URLWithString:weakSelf.storeModel.key_file_url];
                            [[SDWebImageManager sharedManager] loadImageWithURL:key_file options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
                                double key_image_double = [GetSimilarity getSimilarityValueWithImgA:image ImgB:key_image];
                                if (key_image_double >= 0.75) {
                                    [weakSelf performSegueWithIdentifier:@"PacketDetailVC" sender:weakSelf.storeModel];
                                } else {
                                    [self.device addObserver:self forKeyPath:@"adjustingFocus" options:NSKeyValueObservingOptionNew context:nil];
                                }
                            }];
                        }
                    }
                });
            }];
        }
    }
}

首先來(lái)說(shuō)說(shuō)Demo的需求, 其實(shí)需求也就是做一個(gè)類似支付寶AR紅包的APP,新版本的支付寶現(xiàn)在查看不了這個(gè)功能了。需求是這樣的, 首先相機(jī)使用自動(dòng)對(duì)焦拍攝一張圖片,然后埋下紅包或者圖片或者視頻, 然后上傳服務(wù)器。 附近的人查看到當(dāng)前位置有藏得紅包, 圖片或者視頻的時(shí)候, 可以通過(guò)支付寶相機(jī)的自動(dòng)對(duì)焦來(lái)獲取一張圖片和之前上傳服務(wù)器的圖片進(jìn)行對(duì)比,如果圖片匹配相同的, 就會(huì)打開紅包, 圖片或者視頻, 整個(gè)Demo的功能就是這樣的。

但是呢, 在iPhone 5s(我自己的手機(jī)), 上面使用這份代碼測(cè)試沒有一點(diǎn)問題, 但是使用iPhone7測(cè)試這份代碼的時(shí)候, 發(fā)現(xiàn)根本就不能。在iPhone 7上面, 第一次相機(jī)會(huì)很快的會(huì)自動(dòng)對(duì)焦成功, 然后自動(dòng)拍攝一張圖片, 但是這張圖片很模糊或者就是一張純黑的圖片,所以需要重新拍攝一張圖片。在自動(dòng)對(duì)焦成功后的代碼中, 我有使用:

[self.device removeObserver:self forKeyPath:@"adjustingFocus"];

下面的方法是點(diǎn)擊重新拍攝的方法,里面有重新添加自動(dòng)對(duì)焦的KVO:

- (IBAction)actionForPacketCannel:(id)sender {
    [self addTimer];
    self.cameraImg.hidden = YES;
    self.packetHereBtn.hidden = YES;
    self.packetCannelBtn.hidden = YES;
    [self.device addObserver:self
                  forKeyPath:@"adjustingFocus"
                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                     context:nil];
}

但是現(xiàn)在的問題是:在iPhone7上面, 進(jìn)入到VC后,沒有多久, 他就自動(dòng)對(duì)焦成功,然后會(huì)拍攝圖片,但是這個(gè)圖片和iPhone5s上面對(duì)比,相差太遠(yuǎn)了,簡(jiǎn)直就不像是對(duì)焦成功后的,有時(shí)候既然是一張全黑的圖片。既然不是我想要的圖片, 我就按重新選擇圖片,然后重新添加KVO,然相機(jī)又自動(dòng)對(duì)焦,可是這個(gè)時(shí)候,怎么對(duì)焦都不成功!除非我把相機(jī)對(duì)著地板,或者相機(jī)要靠近物件只有幾厘米進(jìn)行對(duì)焦才會(huì)成功, 這個(gè)時(shí)候的圖片拍出來(lái)也是很模糊的。Why? 這是為什么啊 ?怎么感覺iPhone5s 和 iPhone 7 上面的不是一樣的效果,難道是iPhone 7 的手機(jī)相機(jī)又不同之處 ?求大神指點(diǎn)一二,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,692評(píng)論 4 61
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議。它實(shí)...
    香橙柚子閱讀 24,830評(píng)論 8 183
  • 字符集編碼 字符集是一套符號(hào)和編碼。mysql、database、table、column都可以設(shè)置編碼。 更改字...
    StrongZhao閱讀 545評(píng)論 0 0
  • keychain的特點(diǎn)就是不比其他存儲(chǔ)在沙盒中,即使刪除了App,數(shù)據(jù)依然保存在keychain中,如果重新安裝了...
    馬戲團(tuán)小丑閱讀 1,250評(píng)論 0 1
  • 事件描述:這幾天我一直糾結(jié)在老公向我提出離婚的這件事情上,以至于我干什么都無(wú)精打彩,覺得如果我真和他離婚了,自己就...
    張?jiān)?/span>閱讀 177評(píng)論 0 0

友情鏈接更多精彩內(nèi)容