iOS二維碼掃描過程中的光線環(huán)境監(jiān)測(cè)

掃碼過程中的光線監(jiān)測(cè)的實(shí)現(xiàn)效果一般是,在掃碼的過程中,監(jiān)測(cè)光線環(huán)境,比如摩拜單車app,支付寶、微信的掃碼同樣也可以在掃碼的過程中針對(duì)環(huán)境進(jìn)行提醒。

(本文基于iOS原生的API實(shí)現(xiàn)的二維碼掃描)

網(wǎng)上關(guān)于iOS原生API實(shí)現(xiàn)掃描、閃光燈控制方面的文章有很多,這里就不再贅述了。

首先介紹兩個(gè)錯(cuò)誤的實(shí)現(xiàn)思路

1.AVCaptureTorchModeAuto不起作用

只有使用AVCaptureVideoDataOutput作為輸出時(shí),AVCaptureTorchModeAuto才會(huì)起作用,而且亮度的監(jiān)測(cè)只在捕獲最初起作用,并不是連續(xù)監(jiān)測(cè)的,而且我們需要的是實(shí)時(shí)監(jiān)測(cè),所以,AVCaptureTorchModeAuto不能滿足我們的需求。
ZBar應(yīng)該采用的就是設(shè)置AVCaptureTorchModeAuto的方法。

2.[UIScreen mainScreen].brightness跟二維碼沒關(guān)系

網(wǎng)上有的文章說通過NSTimer實(shí)時(shí)獲取這個(gè)值來判斷當(dāng)前光線環(huán)境。brightness這個(gè)值指的是手機(jī)屏幕的亮度級(jí)別,和掃描用的相機(jī)設(shè)備并沒有關(guān)系,而且它的自動(dòng)變化是需要開啟手機(jī)的自動(dòng)亮度調(diào)節(jié)功能的。

綜上,需要找到一個(gè)可以實(shí)時(shí)監(jiān)測(cè)相機(jī)光線環(huán)境的方法。在光線環(huán)境較差的情況下,操作閃光燈的開關(guān)狀態(tài)。

正確的實(shí)現(xiàn)思路

二維碼掃碼我們用到的輸出流是AVCaptureMetadataOutput,對(duì)應(yīng)的代理是AVCaptureMetadataOutputObjectsDelegate。實(shí)現(xiàn)的代理方法是

#pragma mark - 掃描結(jié)果 AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    if (metadataObjects && metadataObjects.count > 0) {
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        NSLog(@"掃描字符串:%@", metadataObject.stringValue)
    }
}

這個(gè)方法里并沒有提供光線環(huán)境監(jiān)測(cè)方面的信息,而且這個(gè)方法只是在掃描結(jié)束才調(diào)用。

我們可以通過音視頻錄制輸出流AVCaptureVideoDataOutput來實(shí)時(shí)監(jiān)測(cè)相機(jī)的光線環(huán)境。

#define brightnessThresholdValue (-0.2) //亮度閾值
#pragma AVCaptureVideoDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
    CFRelease(metadataDict);
    NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
    NSLog(@"當(dāng)前亮度值 : %f",brightnessValue);
    if (brightnessValue < brightnessThresholdValue) {
        dispatch_async(dispatch_get_main_queue(), ^{
            //打開手電筒
            [self turnTorchOn:YES];
        });
    }
}

同一個(gè)AVCaptureSession是可以添加多個(gè)input設(shè)備和多個(gè)output的,所以,我們可以通過同時(shí)使用這兩個(gè)輸出流,來實(shí)現(xiàn)掃碼和光線環(huán)境監(jiān)測(cè)。不過添加前一定要通過- (BOOL)canAddOutput:(AVCaptureOutput *)output;判斷一下,同一個(gè)input/output添加兩次是會(huì)崩潰的

總結(jié):添加一個(gè)相機(jī)輸入設(shè)備的output,添加AVCaptureMetadataOutput解析二維碼,添加AVCaptureVideoDataOutput監(jiān)測(cè)光線環(huán)境。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,252評(píng)論 4 61
  • 自動(dòng)裝箱和拆箱從Java 1.5開始引入,目的是將原始類型值轉(zhuǎn)自動(dòng)地轉(zhuǎn)換成對(duì)應(yīng)的對(duì)象。自動(dòng)裝箱與拆箱的機(jī)制可以讓我...
    codersm閱讀 423評(píng)論 0 0
  • 暫時(shí)還未更新,你的關(guān)注是我持續(xù)更新的動(dòng)力
    在代碼下成長閱讀 173評(píng)論 0 0
  • 關(guān)于溫暖 即使是一個(gè)人,也要有過成一支隊(duì)伍的勇氣。很久以前,我一直秉著這個(gè)勇氣自己一個(gè)人過了好久。 有人說過,習(xí)慣...
    Minhua同學(xué)閱讀 233評(píng)論 0 0
  • 雪在初春的夜晚 靜靜的靜靜的落下 覆蓋了綠茵茵的山 欲開的蕾 和那農(nóng)戶人渴望已久的心 雪告別了飄泊的生活 來到山川...
    笑傲江湖之秋雨閱讀 690評(píng)論 2 2