android-camera2相机开发【2】-动态切换相机预览尺寸

昵称真难选IP属地: 北京
0.846字数 427阅读 2,223

上一篇文章中介绍了相机预览的基本实现,只固定的显示了一个输出尺寸, 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地址

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
4人点赞
更多精彩内容,就在简书APP
"小礼物走一走,来简书关注我"
还没有人赞赏,支持一下
总资产68共写了3.4W字获得177个赞共152个粉丝

推荐阅读更多精彩内容

  • 一.Android中开发相机应用的两种方式 Android系统提供了两种使用手机相机资源实现拍摄功能的方法,一种是...
    GB_speak阅读 5,921评论 2 25
  • 上一篇介绍了如何使用系统相机简单、快速的进行拍照,本篇将介绍如何使用框架提供的API直接控制摄像机硬件。 你还在为...
    Xiao_Mai阅读 7,244评论 4 18
  • 会有一个人跋山涉水 只为寻找你的踪影 会有一个人不远万里 只为追寻你的脚步 世界再大 终究会有人为你心疼 终究你会...
    谂情阅读 237评论 0 2
  • 我家有个27个月的“熊孩子” 跟我挤在一起睡是娃的睡前例行公事,“挤在一起”的说法来自于一篇童话故事,里面的小熊在...
    Amy啊爱米呀阅读 328评论 1 2
  • 中国的书法与国画可谓是博大精深,几千年来一直是在中国的文化底蕴里唯一不可缺少的精神支柱,古时候的人读书少...
    乌领阅读 3,648评论 0 3