android CameraX构建相机拍照

Android CameraX 是一个 Jetpack 支持库,旨在简化相机应用的开发工作。它提供了一致且易用的API接口,适用于大多数Android设备,并可向后兼容至Android 5.0(API级别21)。

CameraX解决了在多种设备上实现相机功能时所遇到的兼容性问题,大大减少了需要编写的设备专属代码量。同时,它还通过提供一种基于用例的、具有生命周期感知能力的方式,简化了相机功能的开发。

导入需要的包

    implementation("androidx.camera:camera-core:1.3.4")implementation("androidx.camera:camera-camera2:1.3.4")implementation("androidx.camera:camera-lifecycle:1.3.4")implementation("androidx.camera:camera-video:1.3.4")implementation("androidx.camera:camera-view:1.3.4")

配置简单layout和PhotoActivity

新建一个activity_photo.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:xhead="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#005dd7"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:layout_margin="20dp"android:background="@drawable/shape_common_dialog_bg"android:orientation="vertical"><androidx.camera.view.PreviewViewandroid:layout_width="640dp"android:layout_height="600dp"android:id="@+id/viewFinder" /><Buttonandroid:layout_marginTop="10dp"android:background="@drawable/shape_login_button"android:id="@+id/image_capture_button"android:layout_width="300dp"android:layout_height="wrap_content"android:elevation="2dp"android:text="拍照" />
</LinearLayout>
public class PhotoActivity implements View.OnClickListener {//图片捕获private ImageCapture imageCapture;//private ProcessCameraProvider cameraProvider;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_photo);}

请求必要的权限

应用需要获得用户授权才能打开相机。
首先在AndroidManifest.xml中声明
<uses-permission android:name="android.permission.CAMERA" />
所以在onCreate(@Nullable Bundle savedInstanceState)方法中增加:

 protected void onCreate(@Nullable Bundle savedInstanceState){String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};if (allPermissionsGranted(permissions, this)) {startCamera();} else {ActivityCompat.requestPermissions(this, permissions, REQUEST_CAMERA_PERMISSION);}
}public boolean allPermissionsGranted(String[] permissions, Context context) {for (String permission : permissions) {int checkSelfPermission = ContextCompat.checkSelfPermission(context, permission);if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, permissions, REQUEST_CAMERA_PERMISSION);}}return true;}

当然用户存在不同意的情况,此时可以重写 onRequestPermissionsResult 方法以处理权限请求结果:

 @Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == REQUEST_CAMERA_PERMISSION) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 权限已被授予,可以执行相机相关操作startCamera();} else {// 权限被拒绝,提示用户需要授权Toast.makeText(this, "需要相机权限才能使用此功能", Toast.LENGTH_SHORT).show();}}}

实现 Preview 用例,开始拍照

我们打开前置摄像头:

 private void startCamera() {ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);cameraProviderFuture.addListener(() -> {try {cameraProvider = cameraProviderFuture.get();//前置摄像头CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;Preview preview = new Preview.Builder().build();// 构建预览用例preview.setSurfaceProvider(bd.viewFinder.getSurfaceProvider());// 构建图片捕获用例imageCapture = new ImageCapture.Builder().build();// 将用例绑定到相机cameraProvider.bindToLifecycle(PersonPhotoActivity.this,cameraSelector,preview,imageCapture);} catch (ExecutionException | InterruptedException e) {throw new RuntimeException(e);}}, ContextCompat.getMainExecutor(this));}
  • ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(this); 这行代码的作用是获取一个ProcessCameraProvider的实例,这个实例可以与宿主的生命周期绑定,从而无需手动管理相机的打开和关闭。
  • cameraProviderFuture注册了一个监听器,当cameraProviderFuture完成时,会执行注册的Runnable。在这个Runnable中,首先通过cameraProviderFuture.get()获取到cameraProvider实例。然后,创建一个用于预览的Preview对象,并将其Surface设置到对应的预览界面上。同时,还创建了一个ImageCapture对象用于图片捕获。
  • 使用cameraProvider.bindToLifecycle()方法将相机与当前Activity的生命周期绑定,并指定使用的摄像头、预览、以及图片捕获的配置。这样,相机就会在Activity的生命周期内自动进行资源的申请和释放

在avd虚拟机中显示

配置avd的前置摄像头为虚拟模式:
在这里插入图片描述
启动项目查看页面:
在这里插入图片描述

拍照

当拍照按钮被点击时调用takePhoto 方法,这里我们建立了一个file对象临时保存当前照片,之后我们就可以自由使用该照片:

 @Overridepublic void onClick(View view) {if (view.getId() == R.id.image_capture_button) {takePhoto(view);}}
 private void takePhoto(View view) {File file = new File(getContext().getExternalCacheDir() + File.separator + System.currentTimeMillis() + ".png");//创建包文件的数据,比如创建文件ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(file).build();//开始拍照imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this),new ImageCapture.OnImageSavedCallback() {@Overridepublic void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {// 关闭相机并释放资源cameraProvider.unbindAll();// file.getPath()//做业务//。。。。}@Overridepublic void onError(@NonNull ImageCaptureException exception) {Log.d(TAG, Objects.requireNonNull(exception.toString()));Toast.makeText(PersonPhotoActivity.this, "照片保存失败", Toast.LENGTH_SHORT).show();}});}

代码分析:

  1. 创建一个ImageCapture.OutputFileOptions对象,用于指定照片的输出选项,这里将照片保存到刚刚创建的File对象中。
  2. 调用imageCapture的takePicture方法开始拍照。传入outputFileOptions作为参数,以及一个回调函数OnImageSavedCallback。
  3. 在OnImageSavedCallback的onImageSaved方法中,当照片成功保存后,关闭相机并释放资源。然后可以进行其他业务操作,如显示照片等。

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

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

相关文章

26.5 Django模板层

1. 模版介绍 在Django中, 模板(Templates)主要用于动态地生成HTML页面. 当需要基于某些数据(如用户信息, 数据库查询结果等)来动态地渲染HTML页面时, 就会使用到模板.以下是模板在Django中使用的几个关键场景: * 1. 动态内容生成: 当需要根据数据库中的数据或其他动态数据来生…

linux使用chattr与lsattr设置文件/目录防串改

背景 linux服务器下,防止某个文件/目录被串改(增删改),可以使用chattr与lsattr设置,这是一种保护机制,用于防止意外地修改或删除重要的文件内容。 chattr与lsattr使用 1.设置目录 图中/tmp/zhk,设置目录属性文件可能被设置为不可更改(immutable)或者只追加(append …

1.Frida框架-Frida环境搭建

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;微尘网校 前置条件&#xff1a;需要科学上网 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F…

python—读写csv文件

目录 csv库方法参数 读取数据 csv.reader方法 文件指定行或列数据读取操作 txt文件的readlines、read方法 csv.DictReader方法 写入数据 txt文件的write&#xff0c;writelines csv.writer方法 csv.DictWriter方法 读写联合(修改及插入数据) 读写csv 文件时&#xf…

【Notepad】Notepad_6.3.1 的中文版安装详情

目录 &#x1f33c;1. Notepad的认识 &#x1f33c;2. Notepad中文版安装详情 &#x1f33c;1. Notepad的认识 Notepad 是 Windows 操作系统中的一个文本编辑器程序&#xff0c;通常用于创建和编辑简单的文本文件&#xff0c;如文本文档 (.txt)。它非常轻量且功能简单&#…

【本地docker启动私有大模型】

一、最终效果 中英文对话 生成代码 二、资源配置 本文选择的模型运行内存需要 4G&#xff0c;因此宿主机建议内存大于8G&#xff0c;CPU建议 6 核以上&#xff1b; 参考博主该mac配置可以相对流畅运行。只需要 CPU资源&#xff0c;不需要 GPU。 三、搭建步骤 启动docker容…

Msfvenom制作自己的专属Shell

Msfvenom制作自己的专属Shell 如何通过Msfvenom来生成用户自己的专属Shell?有时候我们上传Shell到目标主机后&#xff0c;不仅我们自己可以连接&#xff0c;其他用户也可以连接&#xff0c;有时候会导致我们丢失该Shell&#xff0c;甚至该shell被用户发现并查杀。 实验环境 …

如何在 SwiftUI 中开发定制 MapKit 功能

文章目录 介绍地图样式imagery-map 地图交互地图控件总结 介绍 在上一篇文章中&#xff0c;我们探讨了 SwiftUI 中新的 MapKit API 的基础知识。现在&#xff0c;让我们深入 MapKit API 的定制点&#xff0c;以便根据我们的需求定制地图呈现。 地图样式 新的 MapKit API 引入…

LabVIEW开发阀门自动校准装置

1. 装置概述与目标 在工业和实验室环境中&#xff0c;阀门的准确性和稳定性对于流体控制和实验数据的可靠性非常重要。LabVIEW可以作为开发阀门自动校准装置的理想工具&#xff0c;提供高度可定制化的解决方案。 2. 硬件与设备选择 型号选择&#xff1a;为了实现阀门自动校准…

这8款宝藏软件,才是安卓手机必装App!

​AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 1.我的日记——My Diary My Diary 是一款带锁的免费安卓日记工具。 它可用于记录每日日记、秘密想法、旅程、心情追踪或任何私人时刻。 你可…

☺初识c++(语法篇)☺

目录 一命名空间&#xff08;namespace&#xff09;&#xff1a; 二cout与cin简述&#xff1a; 三缺省参数&#xff1a; 四函数重载&#xff1a; 五引用&#xff1a; 六内联函数: 七c中的nullptr简述&#xff1a; 一命名空间&#xff08;namespace&#xff09;&#xff1…

源码编译安装 LAMP

源码编译安装 LAMP Apache 网站服务基础Apache 简介安装 httpd 服务器 httpd 服务器的基本配置Web 站点的部署过程httpd.conf 配置文件 构建虚拟 Web 主机基于域名的虚拟主机基于IP 地址、基于端口的虚拟主机 MySQL 的编译安装构建 PHP 运行环境安装PHP软件包设置 LAMP 组件环境…

住宅代理、移动代理和数据中心代理之间的区别

如果您是一名认真的互联网用户&#xff0c;可能需要反复访问某个网站或服务器&#xff0c;可能是为了数据抓取、价格比较、SEO 监控等用例&#xff0c;而不会被 IP 列入黑名单或被 CAPTCHA 阻止。 代理的工作原理是将所有传出数据发送到代理服务器&#xff0c;然后代理服务器将…

Vuforia AR篇(八)— AR塔防上篇

目录 前言一、设置Vuforia AR环境1. 添加AR Camera2. 设置目标图像 二、创建塔防游戏基础1. 导入素材2. 搭建场景3. 创建敌人4. 创建脚本 前言 在增强现实&#xff08;AR&#xff09;技术快速发展的今天&#xff0c;Vuforia作为一个强大的AR开发平台&#xff0c;为开发者提供了…

maven项目读取文件错误

开发工具&#xff1a;idea 一个简单的maven项目&#xff0c;程序读取不到src/main/resources目录下的文件 寻找了一些原因后&#xff0c;还是没解决&#xff0c;最后灵机一动改了设置居然好了。 然后就解决了

怎样把图片转成pdf文件,简鹿格式工厂轻松批量搞定

信息的存储和分享方式变得越来越多样化&#xff0c;而PDF文件以其跨平台兼容性和内容完整性&#xff0c;成为了许多用户首选的文档格式。无论是在学术研究、商务办公&#xff0c;还是个人创作中&#xff0c;将图片转换为PDF文件的需求日益凸显。 想象一下&#xff0c;当你需要整…

vue学习day04-计算属性、computed计算属性与methods方法、计算属性完整写法

10、计算属性 &#xff08;1&#xff09;概念&#xff1a; 基于现有的数据&#xff0c;计算出来的新属性。依赖于数据变化&#xff0c;自动重新计算。 &#xff08;计算属性->可以将一段求值的代码进行封装&#xff09; &#xff08;2&#xff09;语法&#xff1a; 1&a…

实现桌面动态壁纸(二)

目录 前言 一、关于 WorkerW 工作区窗口 二、关于窗口关系 2.1 窗口以及窗口隶属关系 2.2 桌面管理层窗口组分简析 2.3 厘清两个概念的区别 2.4 关于设置父窗口 三、编写代码以供在 Vista 上实现 3.1 方法二&#xff1a;子类化并自绘窗口背景 四、初步分析桌面管理层…

STM32的SPI接口详解

目录 1.SPI简介 2.SPI工作原理 3.SPI时序 3.1 CPOL&#xff08;Clock Polarity&#xff0c;时钟极性&#xff09;&#xff1a; 3.2 CPHA&#xff08;Clock Phase&#xff0c;时钟相位&#xff09;&#xff1a; 3.3 四种工作模式 4.相关代码 4.1使能片选信号 4.2使能通…

收银系统源代码-收银端UI风格

智慧新零售收银系统是一套线下线上一体化收银系统&#xff0c;给商户提供含线下收银称重、线上商城、精细化会员管理、ERP进销存、丰富营销活动、移动店务助手等一体化的解决方案。 如Windows版收银&#xff08;exe安装包&#xff09;、安卓版收银&#xff08;apk安装包&#…