分享幾個關於Camera的坑

2022-10-26 12:03:40

最近忙於開發一款基於Camera2 API的相機應用,部分功能涉及到廣角鏡頭,因此踩了不少坑,在此與大家分享下以作記錄交流...

經過查閱資料發現在安卓上所謂的廣角鏡頭切換其實是用一個邏輯攝像頭包含多個物理攝像頭實現的,在zoom縮放的時候根據不同的縮放值切換不同的物理攝像頭。
參考:https://source.android.google.cn/devices/camera/multi-camera?hl=zh-cn

踩坑記錄

  1. CameraDevice.TEMPLATE_RECORD的相容性問題
    一般在錄製視訊的時候為了獲得比較穩定的影格率,我們可能會使用CameraDevice.TEMPLATE_RECORD建立CaptureRequest.Builder,但是CameraDevice.TEMPLATE_RECORD在某些鏡頭上
    卻是不可用的,一般表現就是黑畫面,查詢定位發現是相機沒有資料流輸出。

解決方案就是檢視API檔案註釋,發現CameraDevice.TEMPLATE_RECORD是有一定的限制的,我們根據檔案描述做相應的檢測,如果檢測到CameraDevice.TEMPLATE_RECORD不可用時回退到TEMPLATE_PREVIEW即可,
以下是檔案註釋內容:

Create a request suitable for video recording. Specifically, this means that a stable frame rate is used, 
and post-processing is set for recording quality. 
These requests would commonly be used with the CameraCaptureSession.setRepeatingRequest method. 
This template is guaranteed to be supported on all camera devices except DEPTH_OUTPUT devices that are not BACKWARD_COMPATIBLE.
See Also:
createCaptureRequest
  1. 有些鏡頭明明在CameraManager.getCameraIdList中返回了,但是卻無法開啟

後來發現這些不能開啟的攝像頭StreamConfigurationMap的getOutputSizes返回空,也就是說沒有可支援的輸出影象尺寸,因此我們在過濾攝像頭時也需要驗證StreamConfigurationMap是否有支援的尺寸輸出。

// 攝像頭是否可用
 private boolean isEnableCamera(CameraCharacteristics cameraCharacteristics) {
        StreamConfigurationMap configs = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        Size[] sizes = configs.getOutputSizes(ImageFormat.JPEG);
        return null != sizes && sizes.length > 0;
    }
  1. 有些鏡頭有色彩偏差
    在對邏輯鏡頭進行測試時發現,從一個物理攝像頭切換到另外一個物理攝像頭,影象有明顯的色彩偏差,例如下面的兩幅對比圖:

很明顯後面的影象色彩明顯不對,對於這個問題,只要在預覽時將CaptureRequest.CONTROL_CAPTURE_INTENT設定成CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT即可。

  1. 單色鏡頭

android中有一種單色攝像頭,這種攝像頭的預覽影象是灰度圖,預覽圖如下圖所示:

這種攝像頭主要用於輔助拍攝,因此我們在篩選攝像頭時也需要過濾掉這種攝像頭,具體的過濾方法可以參考官方檔案:
單色攝像頭:https://source.android.google.cn/devices/camera/monochrome?hl=zh-cn

這次就和大家分享筆者踩過的這幾個坑,當遇到這些問題時筆者也是花了不少時間精力去定位問題,這裡分享出來希望大家在卷的路上能少走彎路...

推薦閱讀

《關於Camera應用開發進階的乾貨》

關注我,一起進步,人生不止coding!!!