iOS二维码扫描过程中的光线环境监测

扫码过程中的光线监测的实现效果一般是,在扫码的过程中,监测光线环境,比如摩拜单车app,支付宝、微信的扫码同样也可以在扫码的过程中针对环境进行提醒。

(本文基于iOS原生的API实现的二维码扫描)

网上关于iOS原生API实现扫描、闪光灯控制方面的文章有很多,这里就不再赘述了。

首先介绍两个错误的实现思路

1.AVCaptureTorchModeAuto不起作用

只有使用AVCaptureVideoDataOutput作为输出时,AVCaptureTorchModeAuto才会起作用,而且亮度的监测只在捕获最初起作用,并不是连续监测的,而且我们需要的是实时监测,所以,AVCaptureTorchModeAuto不能满足我们的需求。
ZBar应该采用的就是设置AVCaptureTorchModeAuto的方法。

2.[UIScreen mainScreen].brightness跟二维码没关系

网上有的文章说通过NSTimer实时获取这个值来判断当前光线环境。brightness这个值指的是手机屏幕的亮度级别,和扫描用的相机设备并没有关系,而且它的自动变化是需要开启手机的自动亮度调节功能的。

综上,需要找到一个可以实时监测相机光线环境的方法。在光线环境较差的情况下,操作闪光灯的开关状态。

正确的实现思路

二维码扫码我们用到的输出流是AVCaptureMetadataOutput,对应的代理是AVCaptureMetadataOutputObjectsDelegate。实现的代理方法是

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

这个方法里并没有提供光线环境监测方面的信息,而且这个方法只是在扫描结束才调用。

我们可以通过音视频录制输出流AVCaptureVideoDataOutput来实时监测相机的光线环境。

#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(@"当前亮度值 : %f",brightnessValue);
    if (brightnessValue < brightnessThresholdValue) {
        dispatch_async(dispatch_get_main_queue(), ^{
            //打开手电筒
            [self turnTorchOn:YES];
        });
    }
}

同一个AVCaptureSession是可以添加多个input设备和多个output的,所以,我们可以通过同时使用这两个输出流,来实现扫码和光线环境监测。不过添加前一定要通过- (BOOL)canAddOutput:(AVCaptureOutput *)output;判断一下,同一个input/output添加两次是会崩溃的

总结:添加一个相机输入设备的output,添加AVCaptureMetadataOutput解析二维码,添加AVCaptureVideoDataOutput监测光线环境。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,218评论 4 61
  • 自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象。自动装箱与拆箱的机制可以让我...
    codersm阅读 3,068评论 0 0
  • 暂时还未更新,你的关注是我持续更新的动力
    在代码下成长阅读 1,215评论 0 0
  • 关于温暖 即使是一个人,也要有过成一支队伍的勇气。很久以前,我一直秉着这个勇气自己一个人过了好久。 有人说过,习惯...
    Minhua同学阅读 1,553评论 0 0
  • 雪在初春的夜晚 静静的静静的落下 覆盖了绿茵茵的山 欲开的蕾 和那农户人渴望已久的心 雪告别了飘泊的生活 来到山川...
    笑傲江湖之秋雨阅读 3,880评论 2 2