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

这篇具有很好参考价值的文章主要介绍了嵌入式安卓开发:使用Camera2获取相机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Camera2介绍

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

Camera2的主要API类介绍

Camera2获取相机涉及的类如下:
嵌入式安卓开发:使用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");
    }

运行结果如下:
嵌入式安卓开发:使用Camera2获取相机

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

通过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,至此,就可以在界面上看到预览的效果了。

预览效果

如下图所示:
嵌入式安卓开发:使用Camera2获取相机

参考

android camera2 详解说明(一)
Camera2 教程 一概览
Android:Camera2的简单使用
Camera参考详述
camera2使用相机文章来源地址https://www.toymoban.com/news/detail-484496.html

到了这里,关于嵌入式安卓开发:使用Camera2获取相机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用Yocto进行嵌入式Linux开发1 Yocto简介

    Yocto项目是Linux基金会的一个工作组,它是一个开源协作项目,帮助开发人员创建基于Linux的定制系统,这些系统专为嵌入式产品而设计,与产品的硬件架构无关。Yocto项目提供了一个灵活的工具集和开发环境,使世界各地的嵌入式设备开发人员能够通过共享技术、软件栈、配

    2024年02月09日
    浏览(50)
  • 嵌入式开发神器—SourceInsight 4的使用教程(附安装包)

    很多入门嵌入式的初学者所用的代码编写软件都是 IAR、Keil 等 IDE(集成开发环境),这类软件的优点就是既可以编写代码,也可以编译、调试、下载程序,是我们初学者嵌入式开发的利器。 今天给大家介绍的是公司基本上都会用到的神器—SourceInsight,因为在公司项目中,代

    2024年02月10日
    浏览(48)
  • 在嵌入式Linux设备上使用Flutter开发图形界面(试水)

    链接: https://www.bilibili.com/video/BV1qE411N7aC/?spm_id_from=333.880.my_history.page.clickvd_source=0c443477abedebf2fdf7abecef55405d 我是跟着这个视频安装 Docker Desktop for Windows + 启用k8s k8s网址 https://github.com/AliyunContainerService/k8s-for-docker-desktop 主要步骤参照 https://www.toradex.com/zh-cn/blog/zai-qian-ru-shi-linux-sh

    2024年02月21日
    浏览(44)
  • 使用GUI Guider工具开发嵌入式GUI应用 (3) - 使用label组件

    本节讲述在GUI Guider中,应用各种UI的基本元素,并顺利部署到MCU的过程。在GUI Guider中使用各LVGL的组件时,将会涉及到GUI Guider的操作,以及将某些组件额外生成的源码添加到Keil工程中。至于具体产品中的UI应用,可以是这些基本UI元素的组合使用,以实现更加丰富的显示效果

    2024年02月12日
    浏览(56)
  • 使用GUI Guider工具开发嵌入式GUI应用(4)-使用image组件

    在没有使用LVGL和GUI Guider的时候,我想做一个电子相册的小应用,需要在MCU工程中集成一个小型的文件系统和图像解码组件,例如 fatfs (http://elm-chan.org/fsw/ff/00index_e.html)组件和 tjpgdec (http://elm-chan.org/fsw/tjpgd/00index.html)组件。使用GUI Guider显示图片就不需要这么麻烦,可以使

    2024年02月13日
    浏览(63)
  • 【嵌入式Qt开发入门】如何使用Qt进行绘图——QPainter 绘图

            绘图与图表在嵌入式里有的比较多,尤其是图表,我们常在股票里看到的“图表折线/曲线 图/饼状图等”都可以用 Qt 的图表来实现。绘图和图表的内容本章主要介绍绘图和图表的基本操作,以简单的例子呈现绘图与图表的用法,目的就是快速入门绘图与图表,关

    2024年02月12日
    浏览(48)
  • 【嵌入式Linux项目】基于Linux的全志H616开发板智能家居项目(语音控制、人脸识别、安卓APP和PC端QT客户端远程操控)有视频功能展示

    目录 一、功能需求 二、开发环境 1、硬件: 2、软件: 3、引脚分配: 三、关键点 1、设计模式之工厂模式 2、线程 3、wiringPi库下的相关硬件操作函数调用 4、语音模块的串口通信 5、摄像头的实时监控和拍照功能 6、人脸识别 7、qt程序跨平台运行(编译成安卓APP) 四、编译和

    2024年02月15日
    浏览(61)
  • 使用VSCode clangd插件进行linux内核代码阅读和嵌入式开发

    在进行 Linux 内核代码阅读和嵌入式开发时,选择合适的开发工具至关重要。VSCode 是一个流行的跨平台编辑器,并且它的扩展生态系统非常强大。在这篇博客中,我们将介绍如何使用 VSCode Clangd 插件来提高 Linux 内核代码的阅读和嵌入式开发效率。 Clangd 是一个基于 Clang 的语言

    2024年02月09日
    浏览(51)
  • 【嵌入式Qt开发入门】如何使用Qt进行文本读写——QFile读写文本

            在很多时候我们需要读写文本文件进行读写,比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本,比如修改了一个 txt 文件后保存,就需要对这个文件进行读写操作。本文介绍简单的文本文件读写,内容精简,让大家了解文本读写的基本操作。         QFile 类提

    2024年02月12日
    浏览(45)
  • RISC-V IDE MRS使用笔记(十):嵌入式编程开发技巧汇总

    MRS常见嵌入式开发技巧: Q1:如何修改程序编译生成库? A1:在工具栏中点击活动工程的编译配置按钮,在Build Artifact的Tab页面指定目标类型,选中为Static Library 点击Apply and Close应用编译配置。此时会提示建议将调试等级设置为None,优化等级设为Os,这是为了减少生成库的大小

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包