美文网首页各种 demoiOS 画图OpenCV
iOS二维码扫描过程中的光线环境监测

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

作者: SySean | 来源:发表于2017-05-25 16:49 被阅读164次

    扫码过程中的光线监测的实现效果一般是,在扫码的过程中,监测光线环境,比如摩拜单车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监测光线环境。

    相关文章

      网友评论

      • 28bb64fffadd:但是好像按照这个还是不能实时监测光线吧,光线监测就走一次!
        SySean:@鲫鱼博博 对啊,AVCaptureVideoDataOutputSampleBufferDelegate这个代理的回调是一直会走的
        28bb64fffadd:@Sean_W 您那边在光线从亮到暗一直在走嘛?
        SySean:一定是你哪里写的不对吧,我这边没问题啊

      本文标题:iOS二维码扫描过程中的光线环境监测

      本文链接:https://www.haomeiwen.com/subject/hajzxxtx.html