Camera2拍照時部分機型非常暗

一、問題描述

1.部分手機在弱光環境下不管什麼分辨率,預覽和拍出來的照片都非常的暗

2.部分手機在弱光環境下,預覽分辨率1920x1080,輸出圖片分辨率1920x1080時,預覽和拍出來的照片亮度比較亮,但是在預覽分辨率1920x1080,輸出圖片分辨率4000x2250時,預覽和拍出來的照片都非常暗

3.不是調整曝光度(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION)能解決的問題,增加曝光值只是使畫面變得更加蒼白,沒有讓場景本身變得亮起來。

二、解決方案

1.通過設置曝光時間範圍(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE),增加感光元件的曝光時間,接收到更多的光線,使得弱光場景下拍的更亮。

這是調整FPS範圍爲[15,15]時拍攝的效果和之前較暗時效果的對比。

                                               

這裏參考了鏈接https://stackoverflow.com/questions/28429071/camera-preview-is-too-dark-in-low-light-android/49643140#49643140   其中的這個回答:

 previewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, getRange());//This line of code is used for adjusting the fps range and fixing the dark preview
 previewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
 previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);

最終我的預覽previewBuilder相關設置如下:

//設置預覽請求的方式
previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

...

//自動對焦
previewBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
//設置自動曝光幀率範圍
previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,getRange());
 //對焦觸發器設置爲空閒狀態
previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
captureSession.setRepeatingRequest(previewBuilder.build(),captureCallback, mainHandler);

 private Range<Integer> getRange() {
        CameraManager mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
        CameraCharacteristics chars = null;
        try {
            chars = mCameraManager.getCameraCharacteristics(cameraID);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        Range<Integer>[] ranges = chars.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);

        Range<Integer> result = null;

        for (Range<Integer> range : ranges) {
            //幀率不能太低,大於10
            if (range.getLower()<10)
                continue;
            if (result==null)
                result = range;
            //FPS下限小於15,弱光時能保證足夠曝光時間,提高亮度。range範圍跨度越大越好,光源足夠時FPS較高,預覽更流暢,光源不夠時FPS較低,亮度更好。
            else if (range.getLower()<=15 && (range.getUpper()-range.getLower())>(result.getUpper()-result.getLower()))
                result = range;
        }
        return result;
    }

實際代碼中我設置的自動曝光FPS範圍是[10,30],理由是,FPS下限越小,曝光時間越長,那麼接收到的光線越多,拍出來的場景就越亮。FPS的範圍需要有一定的跨度是因爲,FPS太小的時候,比如10,預覽會比較卡,體驗沒那麼好,如果範圍設置成[15,15]這種,全程都很卡。跨度大一點,在光線足夠的時候,FPS會升上去,就不卡了。因爲拍照其實對預覽的幀率要求沒有錄像高,因此犧牲一些幀率大大的提高感光度是可以接受的。關於錄像使用這種方式會比較卡頓的問題,後面會講另一個辦法。

這裏我的代碼中沒有用到CONTROL_AE_LOCK,有些人可能設置了預覽拍照的時候鎖定曝光,或者手動調曝光模式,需要注意了。這個方法是不會起作用,因爲他是設置在自動曝光模式下的FPS範圍,你可能需要設置曝光模式在非鎖定狀態下或自動曝光模式下,才能起作用。

最後,如果預覽的時候亮度正常了,拍照時還是比較暗,需要在拍照的CaptureRequest.Builder也進行這樣的設置。

 

2.設置預覽請求方式爲CameraDevice.TEMPLATE_RECORD,優先保證穩定的幀率,犧牲畫面的質量。

previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);

設置這種預覽請求方式後,即使不設置曝光的FPS範圍,也能在弱光環境下看到比較亮的場景,但是,明顯的感覺到,噪點變多了,畫面沒那麼清晰了,可以做個切換,對比一下畫質。這時也可以去設置曝光FPS的範圍,但是作用不大,甚至讓本來流暢的預覽變得更卡。

最終我的處理是,拍照的時候,預覽方式是CameraDevice.TEMPLATE_PREVIEW,畫質更清晰,弱光時幀率稍低一點,光線足夠時幀率比較流暢。預覽和拍出來的照片亮度都很好。錄製視頻時,預覽方式是CameraDevice.TEMPLATE_RECORD,畫質稍差,無需設置曝光FPS範圍。幀率能夠全程保持流暢,弱光環境下視頻效果也比較亮。

比較了一下輕顏相機,它採取的應該是統一使用CameraDevice.TEMPLATE_RECORD的預覽方式。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章