這段時間有個二維碼掃描的需求,gitHub上大神做的SDK一堆堆。不在累贅敘述。
微信的掃碼功能中,在光線很弱時,會自動彈出個手電筒的按鈕。搜索相關資料,對于后置攝像頭光線強弱的感應,一般是通過捕獲掃碼過程中的圖片,然后獲取整個圖片的亮度平均值來實現的。具體來說,是獲取位圖中每個像素的RGB值,然后求平均值。
來看代碼實現:
給 掃描二維碼的session添加一個 AVCaptureStillImageOutput,做為捕獲圖像的輸出。?
捕捉圖像的實現需要用到下面的一個方法:? captureStillImageAsynchronouslyFromConnection...?
在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,在此基礎上實現的。