嵌入式安卓开发:使用Camera2获取相机

news2024/11/15 4:51:38

文章目录

  • Camera2介绍
  • Camera2的主要API类介绍
    • CameraManager
    • 通过CameraManage获取Cameracharacteristics
    • 通过CameraManage获取CameraDevice
    • 从CameraDevice获取CameraCaptureSession
    • 预览效果
  • 参考

Camera2介绍

  • Android 5.0开始,Google 引入了一套全新的相机框架 Camera2(android.hardware.camera2),并且废弃了旧的相机框架 Camera1(android.hardware.Camera)
  • Camera2相比于Camera的API不仅大幅提高了Android系统拍照的功能,还能支持RAW照片输出,甚至允许程序调整相机的对焦模式、曝光模式、快门等。
  • Camera2相比于Camera更加灵活的同时,也更加的复杂,包含的类更多。

Camera2的主要API类介绍

Camera2获取相机涉及的类如下:
在这里插入图片描述

CameraManager

摄像头管理器。这是一个全新的系统管理器,专门用于检测系统摄像头、打开系统摄像头。除此之外,调用CameraManager的getCameracharacteristics(String)方法即可获取指定摄像头的相关特性。代码如下:

	private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT;//后置相机的ID
    String MyCameraIdStr = Integer.toString(mCameraId);
    private CameraManager mCameraManager;   //相机管理者
    private CameraCharacteristics mCameraCharacteristics;   //相机属性
    float EXPOSURE_TIME_RANGE_min_hz = 0, EXPOSURE_TIME_RANGE_max_hz = 0;
    Range EXPOSURE_TIME_RANGE_msg;//相机曝光时间范围,不可改变
    int CameraInfo_FPS_min, CameraInfo_FPS_max;
    Range[] CameraInfo_FPS_Range;
    int CameraInfo_ISO_min, CameraInfo_ISO_max;
    float[] CameraInfo_Aperture;
    float CameraInfo_Focal_Length[];
    boolean FlagOfCreate = false;

	private void CreateCamera() {   //获取CameraManager,得到相机参数
        mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(MyCameraIdStr);
            Log.d("曝光补偿范围", mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE).toString());
            //上述语句获取相机设备支持的曝光补偿范围
            Log.d("快门时间", mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE).toString());

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        FlagOfCreate = true;
        EXPOSURE_TIME_RANGE_msg = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
        EXPOSURE_TIME_RANGE_max_hz = (float) (1000000000.0 / (long) EXPOSURE_TIME_RANGE_msg.getLower());
        EXPOSURE_TIME_RANGE_min_hz = (float) (1000000000.0 / (long) EXPOSURE_TIME_RANGE_msg.getUpper());
//        Log.d("测试:",String.format("%d",EXPOSURE_TIME_RANGE_msg.getLower()));
//        CameraInfo_FPS_min = (Range[])(mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES))
        CameraInfo_FPS_Range = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
        CameraInfo_FPS_min = (int) CameraInfo_FPS_Range[0].getLower();
        CameraInfo_FPS_max = (int) CameraInfo_FPS_Range[CameraInfo_FPS_Range.length - 1].getUpper();
//        for(int i = 0; i < CameraInfo_FPS_Range.length; ++ i)
//        {
//            Log.d("帧率:",CameraInfo_FPS_Range[i].toString());
//        }
        CameraInfo_ISO_min = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE).getLower();
        CameraInfo_ISO_max = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE).getUpper();

        CameraInfo_Aperture = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
        CameraInfo_Focal_Length = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
//
    }
    public void BtnClick_CameraInfo(View v) {
        if (FlagOfCreate != true) {
            CreateCamera();
        }


        String msg = "";
        msg += "快门速度:" + String.format("%.4f,%.4f", EXPOSURE_TIME_RANGE_min_hz, EXPOSURE_TIME_RANGE_max_hz) + "赫兹\n";
        msg += "相机帧率:" + String.format("%d,%d", CameraInfo_FPS_min, CameraInfo_FPS_max) + " fps\n";
        msg += "ISO::" + String.format("%d,%d", CameraInfo_ISO_min, CameraInfo_ISO_max) + "\n";
        msg += "光圈:";
        for (int i = 0; i < CameraInfo_Aperture.length; ++i) {
            msg += String.format("%f,", CameraInfo_Aperture[i]);
        }
        msg += "\n";
        msg += "焦距:";
        for (int i = 0; i < CameraInfo_Focal_Length.length; ++i) {
            msg += String.format("%f,", CameraInfo_Focal_Length[i]);
        }
        msg += "\n";
        TextMsg.setText(msg);

//        Log.d("CameraInfo","WCC");
    }

运行结果如下:
在这里插入图片描述

可以发现相机的光圈只有一个值,即手机的摄像头光圈是固定的,只有一个光圈值。

通过CameraManage获取Cameracharacteristics

摄像头特性。该对象通过CameraManager来获取,用于描述特定摄像头所支持的各种特性。

相比于旧 API 中的 CameraInfo 类。Cameracharacteristics包括:

曝光补偿(Exposure compensation)、
自动曝光/自动对焦/自动白平衡模式(AE / AF / AWB mode)、
自动曝光/自动白平衡锁(AE / AWB lock)、
自动对焦触发器(AF trigger)、
拍摄前自动曝光触发器(Precapture AE trigger)、
测量区域(Metering regions)、
闪光灯触发器(Flash trigger)、
曝光时间(Exposure time)、
感光度(ISO Sensitivity)、
帧间隔(Frame duration)、
镜头对焦距离(Lens focus distance)、
色彩校正矩阵(Color correction matrix)、
JPEG 元数据(JPEG metadata)、
色调映射曲线(Tonemap curve)、
裁剪区域(Crop region)、
目标 FPS 范围(Target FPS range)、
拍摄意图(Capture intent)、
硬件视频防抖(Video stabilization)等。

在上段的例程中,我们展示了通过CameraManage获取CameraCharacteristics,并显示在界面上。
想更详细地了解相关信息,可以参考:
Android Camera2 之 CameraCharacteristics 详解
官方介绍链接

通过CameraManage获取CameraDevice

在最上面的流程图中,CameraManage只是从Context获取摄像头,并进行管理,此时我们可以获取相机的一些参数。如果想进行拍照获取图像,则还需要获取CameraDevice类对象。
CameraDevice通过CameraManage的openCamera方法在回调函数中获取打开的摄像头,具体代码如下:

	CameraDevice.StateCallback MyDeviceCallback; //摄像头监听,在回调中获取camera device
	CameraDevice MyCameraDevice;
	MyDeviceCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice camera) {//@NonNull后,便会自动对该参数值进行判空。
        Log.d("Camera调试:", "成功获取Camera Device");
        MyCameraDevice = camera;
        takePreview();//获取Camera device后,从Camera device获取Capture Session
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice camera) {
        Log.d("Camera调试:", "获取Camera Device失败");
    }

    @Override
    public void onError(@NonNull CameraDevice camera, int error) {
        Log.d("Camera调试:", "获取Camera Device错误");
    }
};

首先,我们声明了一个CameraDevice.StateCallback类型的对象,该对象的作用是在执行CameraDevice.OpenCamera方法时,将该回调对象传进去,执行OpenCamera后,会自动地调用该回调函数对象。如下:

	if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        Log.d("相机调试:", "没有权限");
        return;
    }
    try {
        mCameraManager.openCamera(MyCameraIdStr, MyDeviceCallback, null);
        //打开相机,监听回调,在回调函数中获取camera device
    } catch (CameraAccessException e) {
        Log.e("相机错误:", "打开摄像头失败");
    }

从CameraDevice获取CameraCaptureSession

CameraCaptureSession的作用是控制相机进行预览或者拍照,可以通过CameraDevice的createCaptureSession方法创建,代码如下:

	CameraCaptureSession MyCameraCaptureSession;    //由CameraDvice创建,控制摄像头预览或拍照
	List<Surface> surfaces;
	surfaces = new ArrayList<>();
	surfaces.add(MySurfaceView.getHolder().getSurface());
try {
			/*
             * 参数
             * outputs 相机流输出的地方
             * callback
             * handler 表示 createCaptureSession 代码运行所在的线程,传null,表示运行在当前线程
             */
	MyCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
   @Override
    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
        MyCameraCaptureSession = cameraCaptureSession;
        Log.d("MyCameraDevice.createCaptureSession:","成功获取CameraCaptureSession");
    }
    @Override
    public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
        Log.d("MyCameraDevice.createCaptureSession:", "获取camera capture session错误");
    }
}, null);
} catch (CameraAccessException e) {
Log.e("开启预览:", "错误,不能访问摄像头");
}

其中createCaptureSession的第一个参数surfaces是指明预览数据流输出的地方,这里我们从界面上获取一个SurfaceView,将SurfaceView目前的Surface放入List surfaces,作为形参传给createCaptureSession,至此,就可以在界面上看到预览的效果了。

预览效果

如下图所示:
在这里插入图片描述

参考

android camera2 详解说明(一)
Camera2 教程 一概览
Android:Camera2的简单使用
Camera参考详述
camera2使用相机

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/464528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

银行数字化转型导师坚鹏:银行数字化转型培训方案

目录 一、银行数字化转型培训背景 二、银行数字化转型模型 三、银行数字化转型课程设计思路 四、 银行数字化转型课程基本介绍 五、 银行数字化转型课程设置 六、银行数字化转型课程大纲 七、培训方案实施流程 一、银行数字化转型培训背景 2020年1月3日&#xff…

2023年IC行业薪资有多高?(内含各岗位薪资对比)

在网上看到一个很火的提问&#xff1a;2023了&#xff0c;IC行业高薪还在吗&#xff1f;其实这也是很多同学比较关注的一个问题&#xff0c;下面我们就一起来了解一下IC行业薪资有多高。 不同高校层次硕士-IC设计薪资情况 从不同岗位类型的offer占比情况来看&#xff0c;从事I…

SaaS云HIS系统源码功能介绍

SaaS云HIS首页功能&#xff1a;包括工作计划、预警、主功能菜单、医院机构公告。 一、工作计划 1.值班概况&#xff1a;值班日期、值班时间、值班科室&#xff08;内科、外科等&#xff09; 2.待处理患者&#xff1a;内科人数、外科人数等 病历统计&#xff1a;入院病历、出…

Java冒泡排序(Bubble Sort)算法实例

何为冒泡排序&#xff1f; 冒泡&#xff1a;就像气泡从水中冒出来一样 在冒泡排序中&#xff0c;最小数或最大数取决于您是按升序还是降序对数组进行排序&#xff0c;向上冒泡到数组的开头或结尾。算法描述&#xff1a; 比较相邻的元素。如果第一个比第二个大&#xff0c;就交…

【网络编程】

1.网络基础&#xff08;见PDF文件&#xff09; file:///D:/0graduate/000%E5%AE%9E%E4%B9%A0%E5%B0%B1%E4%B8%9A/C/webserver/4.1/%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80.pdf 2.协议 UDP协议 TCP协议 源端口号&#xff1a;发送方端口号目的端口号&#xff1a;接收方端口号序…

Dubbo (1)

目录 认识RPC Dubbo 认识RPC RPC是解决不同JVM之间数据调用的一个思想&#xff0c;比如说现在有2台不同的机器&#xff0c;业务代码需要在这2台机器间调用后台业务代码&#xff0c;RPC就可以解决这2台机器业务代码调用的问题&#xff1a; 而RPC实现流程是什么样的呢&#xff…

中文版gpt-最新的人工智能gpt

最新的人工智能gpt 什么是GPT&#xff1f; GPT是一种自然语言处理和语言生成技术&#xff0c;它能够学习和理解自然语言&#xff0c;并生成高质量的文本。GPT是由OpenAI开发的&#xff0c;它采用了最新的深度学习技术&#xff0c;具备了强大的自我学习能力和语言理解能力。它…

Mybatis关联查询【附实战案例】

目录 相关导读 一、Mybatis一对一关联查询 1. 新增持久层接口方法 2. 新增映射文件对应的标签 3. 新增测试方法 4. 运行效果 二、Mybatis一对多关联查询 1. 新增持久层接口方法 2. 新增映射文件对应的标签 3. 新增测试方法 4. 运行效果 三、Mybatis多对多关联查询 …

HCL Nomad Web 1.0.7发布和新功能验证

大家好&#xff0c;才是真的好。 要问在HCL Notes/Domino系列产品中&#xff0c;谁更新得最快&#xff0c;那么答案一定是HCL Nomad Web。 你看上图右边&#xff0c;从1.0.1更新到1.0.7&#xff0c;都没花多少时间。 从HCL Nomad Web 1.0.5版本开始&#xff0c;可以支持直接…

逐浪智能时代,网易数帆“重写”低代码

如今&#xff0c;越来越多行业正驶入数字化转型的深水区&#xff0c;如何彻底释放数据生产力&#xff0c;成为所有企业的一道必答题。 4月25日&#xff0c;“网易数帆低代码业务战略发布会”在线上举行。在发布会上&#xff0c;网易数帆发布了CodeWave智能开发平台&#xff0c…

C#之Class的实例化过程

总目录 文章目录 总目录前言一、class的成员二、实例化顺序&#xff08;无继承情况&#xff09;1.声明时进行初始化2.在构造函数中初始化 三、实例化顺序&#xff08;有继承情况&#xff09;结语 前言 在平常开发的过程中&#xff0c;经常需要new 一个class&#xff0c;但是呢…

平安银行广州分行:以金融赋能慈善 释放更大社会效能

4月8日&#xff0c;平安银行广州分行“为爱徒步 欢乐‘益’起行”活动在广州市白云区钟落潭镇云溪湾新乡村示范带圆满举行。本次活动由平安银行广州分行主办&#xff0c;通过白云区供销合作联社组织&#xff0c;在助农过程中&#xff0c;同时公益捐步&#xff0c;助力建设云溪湾…

gitlab部署及整合Jenkins持续构建(三)sonarqube9.9安装和使用(一步一坑)

文章目录 postgresql13.0安装1、配置postgresql数据库2、进入postgresql创建数据库 代码质量管理平台--sonarqube安装1、前置依赖下载2、安装unzip并解压sonarqube并移动到/usr/local&#xff1a;3、修改sonarqube相应的配置4、新增用户&#xff0c;并将目录所属权赋予该用户&a…

资料链接 网络/系统/华为

网络&#xff1a; 缺省路由 https://www.cnblogs.com/ricksteves/p/9702546.html AC热备 快搜预览中心https://search.ruijie.com.cn:8447/rqs/preview.html?wdeHAiOjE1NDU4NzUxNDcsIm5iZiI6MTU0NTYxNTk0N302018092015272000303LqqZuvMhE7V7Ygl6r5RWsTHbWazT BGP https:…

nextjs 错误日志收集

最近用nextjs开发一款房产渠道管理的系统&#xff0c;从开始的项目管理&#xff0c;到价格单管理、订单管理、团队管理、中介管理、个人信息管理...等等功能越来越多的时候&#xff0c;前端偶现的问题不容易发现&#xff0c;造成了不必要的麻烦&#xff0c;就想搞个错误日志收集…

地理信息系统有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是几本地理信息系统领域的SCI期刊推荐&#xff1a; International Journal of Geographical Information Science: 这是一个国际性的期刊&#xff0c;它涵盖了地理信息科学的所有领域&#xff0c;包括地图学、遥感、空间分析、地理信息系统、地理信息技术、地球信息学等等…

被chatGPT割了一块钱韭菜

大家好&#xff0c;才是真的好。 chatGPT热度一直上升&#xff0c;让我萌生了一个胆大而创新的想法&#xff0c; 把chatGPT嵌入到Notes客户机中来玩。 考虑到我已经下载了一个chatGPT的Notes应用&#xff08;请见《ChatGPT APIs for HCL DOMINO》&#xff09;&#xff0c;想着…

Shell编程之条件语句

目录 一、条件测试 1&#xff09;test命令 ​编辑 2&#xff09;文件测试 常用的测试操作符 ​编辑 4&#xff09;整数值比较 常用的测试操作符 6&#xff09;逻辑测试 常用的测试操作符 7&#xff09;三元运算符 二、if语句 1&#xff09;单分支结构 2&#xff09…

时序预测 | MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元时间序列预测

时序预测 | MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元时间序列预测 目录 时序预测 | MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元时间序列预测 基于鲸鱼算法优化门…