这段时间有个二维码扫描的需求,gitHub上大神做的SDK一堆堆。不在累赘叙述。
微信的扫码功能中,在光线很弱时,会自动弹出个手电筒的按钮。搜索相关资料,对于后置摄像头光线强弱的感应,一般是通过捕获扫码过程中的图片,然后获取整个图片的亮度平均值来实现的。具体来说,是获取位图中每个像素的RGB值,然后求平均值。
来看代码实现:
AVCaptureStillImageOutput给 扫描二维码的session添加一个 AVCaptureStillImageOutput,做为捕获图像的输出。
捕捉图像的实现需要用到下面的一个方法: captureStillImageAsynchronouslyFromConnection...
captureStillImage在handle的block中,需要获取图像 的平均亮度值。前人栽树,后人乘凉。用到了GetImageBright这个类。 在扫描时由于 我们需要 不断去捕捉这个亮度,所以添加个定时器,间隔一定时间去执行这个函数就可以啦。
啰嗦一下搜集资料和思考的过程。刚开始 我是尝试添加新的session 去执行这个捕获的任务。中间用到 AVCaptureVideoDataOutputSampleBufferDelegate 这个的代理方法,也能 捕捉到图像,从而获取亮度值。但是一到代理执行时,画面就会卡住。多次尝试无果后,看到有个AVCaptureConnection 的类。以此为突破点去搜索 一个Session,一个Input,多个Output的方法。哈~~果断可以。
/***********************重要更新***********************/
下午无意间运行Demo,发现上述方法有个致命bug,captureStillImageAsynchronouslyFromConnection 方法调用时,相机拍照的声音会一只存在。由于需要不断获取静态图片,添加 反向声音进行隐藏的方法也不好使。(隐藏相机声音的方法)
继续回到AVCaptureVideoDataOutputSampleBufferDelegate这个 方式。添加AVCaptureVideoDataOutput的端口输出。依旧是一个Session,一个Input,多个Output的方法。依据此代理发法中得到的sampleBuffer就可直接得到位图buffer的首地址,从而得出这一帧图像的平均RGB值。
unsigned char * baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
新知识或技术的学习和掌握是一个由浅入深的过程,这个过程也许是多读几本书就能完成的,也可能是我们在出错和尝试中不断摸索才能体会的。有的人喜欢前者,而我更乐意用后者。
Just try it !
二维码的实现Copy了大神的Demo,在此基础上实现的。
网友评论
答应错误日志是:invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.