android-camera2相機開發【2】-動態切換相機預覽尺寸

上一篇文章中介紹了相機預覽的基本實現,只固定的顯示了一個輸出尺寸, android 設備相機實際可以支持輸出很多尺寸的圖像,不同的設備具體尺寸數值不同,通過系統提供的方法可以獲取設備支持的輸出尺寸,具體的操作可以參考上一篇文章中的相關內容。

本文在上一篇文章的基礎上進行調整,實現的效果是,添加一個按鈕,點擊的時候切換相機輸出尺寸,更新預覽界面。

1. 簡單的工具類

將一些簡單的相機的操作封裝程一個工具類,能獲取指定的相機,相機輸出尺寸列表,釋放相機資源,具體代碼如下。

public class CameraUtils {
    private static CameraUtils ourInstance = new CameraUtils();

    private static Context appContext;
    private static CameraManager cameraManager;

    public static void init(Context context){
        if (appContext == null) {
            appContext = context.getApplicationContext();
            cameraManager = (CameraManager) appContext.getSystemService(Context.CAMERA_SERVICE);
        }
    }

    public static CameraUtils getInstance() {
        return ourInstance;
    }

    private CameraUtils() {

    }

    public CameraManager getCameraManager(){
        return cameraManager;
    }

    public String getFrontCameraId(){
        return getCameraId(true);
    }

    public String getBackCameraId(){
        return getCameraId(false);
    }

    /**
     * 獲取相機id
     * @param useFront 是否使用前置相機
     * @return
     */
    public String getCameraId(boolean useFront){
        try {
            for (String cameraId : cameraManager.getCameraIdList()){
                CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
                int cameraFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (useFront){
                    if (cameraFacing == CameraCharacteristics.LENS_FACING_FRONT){
                        return cameraId;
                    }
                }else {
                    if (cameraFacing == CameraCharacteristics.LENS_FACING_BACK){
                        return cameraId;
                    }
                }
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 根據輸出類獲取指定相機的輸出尺寸列表
     * @param cameraId 相機id
     * @param clz 輸出類
     * @return
     */
    public List<Size> getCameraOutputSizes(String cameraId, Class clz){
        try {
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
            StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            return Arrays.asList(configs.getOutputSizes(clz));
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 根據輸出格式獲取指定相機的輸出尺寸列表
     * @param cameraId 相機id
     * @param format 輸出格式
     * @return
     */
    public List<Size> getCameraOutputSizes(String cameraId, int format){
        try {
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
            StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            return Arrays.asList(configs.getOutputSizes(format));
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 釋放相機資源
     * @param cameraDevice
     */
    public void releaseCamera(CameraDevice cameraDevice){
        if (cameraDevice != null){
            cameraDevice.close();
            cameraDevice = null;
        }
    }
}

2. 初始化相機

使用工具類,初始化一些相機相關的參數,後面打開相機的時候直接使用即可,省去了上一篇文章 configCamera() 配置相機的步驟。

    private void initCamera(){
        cameraManager = CameraUtils.getInstance().getCameraManager();
        cameraId = CameraUtils.getInstance().getCameraId(false);//默認使用後置相機
        //獲取指定相機的輸出尺寸列表
        outputSizes = CameraUtils.getInstance().getCameraOutputSizes(cameraId, SurfaceTexture.class);
        //初始化預覽尺寸
        previewSize = outputSizes.get(0);
    }

3. 點擊按鈕切換輸出尺寸,更新預覽界面

點擊按鈕時,在相機輸出尺寸列表中進行循環,依次使用選定的尺寸構造預覽界面。

        btnChangePreviewSize.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //切換預覽分辨率
                updateCameraPreview();
                setButtonText();
            }
        });

    private void updateCameraPreview(){
        if (sizeIndex + 1 < outputSizes.size()){
            sizeIndex++;
        }else {
            sizeIndex = 0;
        }
        previewSize = outputSizes.get(sizeIndex);
        //重新創建會話
        createPreviewSession();
    }

    private void setButtonText(){
        btnChangePreviewSize.setText(previewSize.getWidth() + "-" + previewSize.getHeight());
    }

總結

經過上面的步驟,點擊按鈕時就可以預覽不同輸出尺寸的圖像。

可以發現,不同的預覽尺寸由於和預覽窗口寬高比不同,造成不同程度的圖像拉伸,需要進一步優化,後續文章進行實現。

項目代碼github地址

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