iOS获取环境光强度

538 阅读2分钟

获取环境光强度,一般有两种途径:1、根据拍摄的多张图片数据计算平均亮度值。2、使用摄像头光传感器直接读取。

光照度的单位是勒克斯,是英文lux的音译,但是iOS系统检测的值是一个大致的范围。然而App Store上有诸多测试光照度的App,显示数值单位是勒克斯,笔者目测应该是用一个标准光源校准了后,换算了光照度单位。笔者也测试了多款App,对于相同的光源测试结果差别还是很明显的。

完整代码

比较简单直接上代码:

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController () <AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureDevice *device;
@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];

    // 1、获取硬件设备
    self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // 2、创建输入流
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];

    // 3、创建设备输出流
    AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
    [output setSampleBufferDelegate:self queue: dispatch_get_main_queue()];

    // 4、AVCaptureSession属性定要定义为全局属性,确保有对象在一直引用AVCaptureSession对象;
    // 否则会造成AVCaptureSession对象提前释放,无法获取数值;
    self.session = [[AVCaptureSession alloc]init];

    // 5、设置为高质量采集率
    self.session.sessionPreset = [self sessionPreset];

    // 6、添加会话输入和输出
    if ([self.session canAddInput:input]) {
        [self.session addInput:input];
    }
    if ([self.session canAddOutput:output]) {
        [self.session addOutput:output];
    }

    // 7.启动会话
    [self.session startRunning];
}

#pragma mark- 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];

    CGFloat brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];

    NSLog(@"当前亮度参数:%f",brightnessValue);

}

- (NSString *)sessionPreset {
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPreset3840x2160]) {
        return AVCaptureSessionPreset3840x2160;
    }
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1920x1080]) {
        return AVCaptureSessionPreset1920x1080;
    }
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]) {
        return AVCaptureSessionPreset1280x720;
    }
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
        return AVCaptureSessionPreset640x480;
    }
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288]) {
        return AVCaptureSessionPreset352x288;
    }
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPresetHigh]) {
        return AVCaptureSessionPresetHigh;
    }
    if ([self.device supportsAVCaptureSessionPreset:AVCaptureSessionPresetMedium]) {
        return AVCaptureSessionPresetMedium;
    }
    return AVCaptureSessionPresetLow;
}

@end

注意事项

  • 注意要引入AVFoundation框架。
  • 在info文件中添加相机Camera的使用描述。
  • AVCaptureSession对象要确保强引用,不会提前释放。
  • 查询了下有人说参数范围大概在-5~~12之间,参数数值越大,环境越亮,但是笔者测试的大致范围是-10.5~9,有知晓准确数值范围的的还请不吝赐教,留言告知。