Camera2适用是Android5.0(API 级别 21)或更高版本的所有设备

总览

  • 1、加入权限
    • 1.1 系统Android6.0以下
    • 1.2 系统Android6.0以上或者更高版本
  • 2、实现功能列表
    • 2.1 Camera2基础(入门篇)
      • 2.1.1 显示预览图
      • 2.1.1 摄像头方向切换
      • 2.1.2 预览图片出现拉伸情况处理
      • 2.1.3 手动对焦和自动对焦
      • 2.1.4 缩放镜头大小
    • 2.2 图片
      • 2.2.1 图片拍摄
      • 2.2.2 图片剪辑
    • 2.3 视频
      • 2.3.1 视频录制
      • 2.3.2 视频剪辑
      • 2.3.3 直播流程
    • 2.4 保存处理
      • 2.4.1 视频分段保存
      • 2.4.2 图片压缩

1、加入权限

(所需要的的权限有:读写文件权限、拍摄照片和录制视频权限、 录音权限)

1.1 系统Android6.0以下

  • 系统Android6.0以下的版本的直接在AndroidManifest.xml加入*
 // 读写权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_CALENDAR" />// 拍摄照片和录制视频权限<uses-permission android:name="android.permission.CAMERA"/> // 录音权限<uses-permission android:name="android.permission.RECORD_AUDIO"/>

1.2 系统Android6.0以上或者更高版本

  • 系统Android6.0或者更高版本需要动态获取权限(一般应用安装第一次打开获取,只获取一次就好)*
 //先把所需要的的权限用数组装起来//READ_CALENDAR、WRITE_EXTERNAL_STORAGE : 读写权限//CAMERA : 拍摄照片和录制视频权限//RECORD_AUDIO: 录音权限private static String[] PERMISSIONS_STORAGE = {"android.permission.READ_CALENDAR","android.permission.WRITE_EXTERNAL_STORAGE","android.permission.CAMERA","android.permission.RECORD_AUDIO"};public void verifyStoragePermissions(Activity activity) {//然后通过其中的一个函数来申请int checkSelfPermission = ActivityCompat.checkSelfPermission(activity, PERMISSIONS_STORAGE[0]);if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {// 没有写的权限,去申请写的权限,会弹出对话框ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);}}

2、实现功能列表

2.1 Camera2基础(入门篇)

2.1.1 显示预览图

  1. 利用渲染图层中TextureView.SurfaceTextureListener监听,以下为监听的方法解析
方法 解析
onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) 当TextureView准备好使用Surface的SurfaceTexture时调用 (在这个方法里面做打开相机操作)
onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) SurfaceTexture的缓冲区大小更改时调用
onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) 在将SurfaceTexture要销毁指定的对象时调用
onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) SurfaceTexture通过更新指定的值 时调用
  1. 接收有关摄像头设备状态的更新CameraDevice.StateCallback(其中包括:摄像头打开,摄像头关闭,打开摄像头错误原因)
方法 解析
onOpened( CameraDevice camera) 照相机设备完成打开时调用的方法
onDisconnected(CameraDevice camera) 当照相机设备不再可用时调用的方法(一般是其他应用占用了会回调,释放资源,调用camera.close())
onError(CameraDevice camera, int error) 相机设备遇到严重错误时调用的方法(一般会释放资源,调用camera.close())
  • 在onOpened(CameraDevice camera) 得到CameraCaptureSession(一个用于接收有关摄像机捕获会话状态更新的回调对象)
/*** 渲染图层*/private final TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {surface = new Surface(surfaceTexture);openCameraBase();}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}};/*** 摄像头状态回调*/private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {@Overridepublic void onOpened(@NonNull CameraDevice camera) {//成员变量device = camera;try {device.createCaptureSession(Collections.singletonList(surface), new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraCaptureSession session) {cameraCaptureSession = session;try {//创建一个请求//TEMPLATE_PREVIEW:创建适合摄像机预览窗口的请求//TEMPLATE_MANUAL:用于捕获参数的直接应用程序控制的基本模板//TEMPLATE_RECORD:创建适合视频录制的请求//TEMPLATE_STILL_CAPTURE:创建适合静态图像捕获的请求//TEMPLATE_VIDEO_SNAPSHOT:创建一个适合在录制视频时捕获静态图像的请求//TEMPLATE_ZERO_SHUTTER_LAG:创建一个适合零快门滞后仍然捕获的请求builder = device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);//在此请求的目标列表中添加一个表面builder.addTarget(surface);cameraCaptureSession.setRepeatingRequest(builder.build(), null, null);} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onConfigureFailed(@NonNull CameraCaptureSession session) {}}, null);} catch (CameraAccessException e) {e.printStackTrace();}Log.i(TAG, "onDisconnected: " + "摄像头已打开");}@Overridepublic void onDisconnected(@NonNull CameraDevice camera) {camera.close();device.close();Log.i(TAG, "onDisconnected: " + "摄像头已关闭");}@Overridepublic void onError(@NonNull CameraDevice camera, int error) {camera.close();}};/*** 打开摄像头*/private void openCameraBase() {//摄像头管理 获取系统服务CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);//判断系统摄像机权限if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//权限处理verifyStoragePermissions(getContext());}try {//打开摄像头assert cameraManager != null;cameraManager.openCamera(cameraDirection, stateCallback, null);} catch (CameraAccessException e) {e.printStackTrace();}}

注意:当切换到后台再进来会发现预览图画面卡着问题(是因为相机关闭了,渲染图层TextureView.SurfaceTextureListener没有清除图层,所以会以为画面卡着),解决方案如下:

 /*** 防止其他应用占用摄像头,所以每一次进去都新打开摄像头*/@Overrideprotected void onResume() {super.onResume();openCameraBase();}/*** (关闭相机)释放资源*/@Overrideprotected void onPause() {super.onPause();if (device != null) {device.close();}}

2.1.1 摄像头方向切换

在 cameraManager.openCamera(cameraDirection, stateCallback, null);中cameraDirection是控制摄像头的方向(摄像头方向:“1”:为前置 “0”:为后置 (默认值为0))

    //切换摄像头binding.button2.setOnClickListener(v -> {if (device.getId().equals(index)) {cameraDirection = "1";} else {cameraDirection = "0";}//先关闭,再打开device.close();openCameraBase();});

注意:记得先关闭当前摄像头,再打开要切换的摄像头

2.1.2 预览图片出现拉伸情况处理

  • 一、自定义TextureView,重写宽高
  • 二、初始化控件
 private int ratioW = 0;private int ratioH = 0;public void setAspectRation(int width, int height){if (width < 0 || height < 0){throw new IllegalArgumentException("width or height can not be negative.");}ratioW = height;ratioH = width;//请求重新布局requestLayout();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);if (0 == ratioW || 0 == ratioH){//未设定宽高比,使用预览窗口默认宽高setMeasuredDimension(width, height);}else {//设定宽高比,调整预览窗口大小(调整后窗口大小不超过默认值)if (width < height * ratioW / ratioH){setMeasuredDimension(width, width * ratioH / ratioW);}else {setMeasuredDimension(height * ratioW / ratioH, height);}}}

注意:用法在跟TextureView控件一样,其他没有变

2.1.3 手动对焦和自动对焦

2.1.4 缩放镜头大小

2.2 图片

2.2.1 图片拍摄

2.2.2 图片剪辑

2.3 视频

2.3.1 视频录制

2.3.2 视频剪辑

2.3.3 直播流程

2.4 保存处理

2.4.1 视频分段保存

2.4.2 图片压缩

学习Camera2自定义相机从入门到高级一篇就够了相关推荐

  1. Android Camera2自定义相机绿屏

    一.问题现象 在项目中使用Camera2自定义相机拍照,在其他手机上没有问题.在华为P40上.相机预览出现绿屏,绿屏如下所示 二.问题原因 预览设置高宽参数不符合相机高宽的话就会有绿条 原来的设置代码 ...

  2. docker入门,这一篇就够了。

    Docker入门,这一篇就够了. Docker容器虚拟化平台. 前言 接触docker很长时间了,但是工作中也没有用到,所以总是学了忘,忘了学.不过这次,我打算跟大家分享一下我的学习历程,也算是我的独 ...

  3. Docker入门实战看这篇就够了(最新详细以及踩过的坑)

    Docker入门实战看这篇就够了 前言 初识 是什么 容器与虚拟机 能干什么 去哪玩 安装 先决条件 查看自己的内核 安装所需的软件包(支持devicemapper存储类型) 设置镜像的仓库 设置yu ...

  4. Git【入门】这一篇就够了

    前言 Git[入门]这一篇就够了 欢迎关注公众号,白嫖原创PDF,也可以催更,微信搜:JavaPub,回复:[666] Git 在生产工作中是使用频率很高的工具,但我发现很多文章只是对它做了简单的提交 ...

  5. Spring入门,看这篇就够了

    Spring入门,看这篇就够了 文章目录 Spring入门,看这篇就够了 一. 初识Spring 二.Spring Framework系统架构 三.核心概念 1.IoC(inversion of co ...

  6. Android 自定义相机Demo 入门学习

    Android 自定义相机Demo 本文是参考网上一些自定义相机示例,再结合自己对相机的功能需求写的,基本上包含了很多基本功能,比如相机对焦.闪光灯,以及在手机预览界面上绘制自己想要绘制的图案. 话不 ...

  7. Android开发(Jetpack) 学习CameraX 自定义相机实现

    目录 一.CameraX和Camera2 二.CameraX的引入 三.自定义拍照 四.自定义视频录制 五.XML 配置 一.CameraX和Camera2 CameraX 是一个 Jetpack 库 ...

  8. 超硬核Python避坑学习方案奉上!入门到就业一篇就搞定!

    本文收录了python从基础入门到高级进阶,再到之后发展方向的详细介绍,欢迎小伙伴们关注阅读!相信对你的python学习之路定能助一臂之力!评论提出你的见解!大家一起为你解答! 目录 一.迈出开发的第 ...

  9. Spring Cloud入门,看这篇就够了!

    点击▲关注 "中生代技术"   给公众号标星置顶 更多精彩 第一时间直达 概述 首先我给大家看一张图,如果大家对这张图有些地方不太理解的话,我希望你们看完我这篇文章会恍然大悟. 什 ...

  10. mybatis-plus学习(一)——入门看这一篇就够了

    文章目录 前言 准备工作 1.需要准备的SQL 2.一个简单的maven项目 3.配置文件如下 4.建立一个简单的实体和mapper 5.简单的helloworld测试程序 基本使用 通用mapper ...

最新文章

  1. mysql custom_MySQL安装教程
  2. 项目进度管理:定义活动
  3. 【-】WebKit Layout (布局)
  4. 使用机器学习预测天气_如何使用机器学习预测着陆
  5. 在阿里云服务器centOs7系统中部署.NET Core项目
  6. android 自定义dialog 定时关闭,Android 快速实现自定义 Dialog
  7. pycharm通过pytest运行报错:No test were found 解决
  8. System.Data.OleDb.OleDbException: 未指定的错误的解决方法
  9. 练手|常见近30种NLP任务的练手项目
  10. 简易的文件上传 tp5
  11. pclzip.lib.php,LimeSurvey
  12. 东北大学毕业设计(论文)全程解析
  13. 错误: -source 1.6 中不支持 diamond 运算符的解决办法
  14. 一份超详细的Spring4常用知识清单!
  15. 理解Tensorflow的shape
  16. 首次试水天池数据大赛——7个小时玩了把美年健康AI大赛
  17. 移动支付申请所需材料及流程整理
  18. 数据窗口Pageup与Pagedown翻页
  19. 用IE点击html页面用谷歌打开,如何在电脑中使用谷歌浏览器打开不兼容的网页
  20. mysql:SQL语言包含4个部分

热门文章

  1. php中怎么获取提交时间,php – 通过curl_getinfo()获取详细信息来获取cURL请求的时间...
  2. cdr2018更新内容
  3. TIPS-国库信息处理系统
  4. css3线性渐变怎么写,CSS3线性渐变指南
  5. labwindows 多线程
  6. 如何科学地利用A/B测试快速迭代产品?
  7. 常用数字信号处理方法在matlab上的实现(目录和先导)
  8. 40年间,“国货”如何崛起
  9. U盘/移动硬盘 有写保护怎么解除【未解决】
  10. 程序员薪酬待遇大调查:学哪种语言的最赚钱?