android image设置adjustviewbounds_探索 Android 平台的 CameraX

前言

如果你曾经用过 Android 的 Camera APIs,你可能已经感受到了,它们一直没有成为最容易实现的东西。最开始是 Camera API,然后又推荐使用 Camera2 API — 这个升级是为了让开发者在使用 Android 的相机 API 时有更好的体验。然而,使用相机的 API (即使是最简单的使用)时还是会有很多脏代码,而且,在 Android 应用中要实现 Camera 功能时还是会很困难。

幸运的是,新的 CameraX API 给相机功能开发提供了更简单的解决方案以帮助我们减轻这些痛苦。另外,CameraX 基于 Camera2 API 实现,它极大地简化了在 minSdk 21 及以上版本的实现过程。这篇文章将会研究 CameraX API 的第一部分,了解 Camera API 是什么以及我们如何在 App 中开始使用它。

第一次看我文章的小伙伴可以关注一下我,顺便关注一下我的专栏:Android进阶每天更新各种技术干货,希望更多人能加入进来,一起学习交流,走在技术前面。

Android进阶​zhuanlan.zhihu.com
022d850cd64b0b52a31cc151dbabbc4c.png

配置 CameraX

CameraX 由两个概念来完成实现 -- Camera View 和 Camera Core。Camera View 可被单独用于处理基本的相机要求,比如拍照,录视频,生命周期管理以及相机切换等。而核心库能够搭配 Camera View 处理更复杂的 CameraX 实现(比如在当前的相机上下文提供一个取景器)。我们将会在这篇文章中看看 CameraView 组件是怎么工作的。

开始使用 CameraX 之前,我们需要一些配置步骤。放心,从添加权限到在你的 app 里有一个简单的 camera 实现,不会有很多步骤(甚至也不会有很多代码)。

c14f4b9f7b90976b4f1f46e104afd6d9.png

首先在应用的 manifest 添加 Camera 权限:

<uses-permission android:name="android.permission.CAMERA" />

然后,需要添加必要的依赖:

def camerax_version = "1.0.0-alpha01"
// 添加 CameraX core 
“androidx.camera:camera-core:${camerax_version}”
// 添加 CameraX Camera2 API 互操作支持
implementation “androidx.camera:camera-camera2:${camerax_version}”

注意:CamaraView 现在还不可用,但你可以在这里看源码。因为这个原因,实现的细节未来可能会有变化。

你可能注意到了,这里有两个不同的依赖:

  • Camera Core 库为使用 CameraX 库提供了必要的类
  • CameraX Camera2 依赖提供了一些互操作功能所以我们能够在 CameraX 中集成一些已有的 Camera2 实现。

有了上面的准备工作,我们现在可以看看如何在我们的应用里实现 Camera view 组件了。

Camera View

正如上文所说,CameraView 给开发者提供了方法,使他们不需要太多困难就可以在 app 里提供基础的 camear 实现。我们能够在布局文件里直接添加这个组件:

<androidx.camera.view.CameraViewandroid:id="@+id/view_camera"android:layout_width="match_parent"android:layout_height="match_parent" />

这个 CameraView 类是一个 ViewGroup,本质上包含了一个 TextureView 来显示 camera 流,以及配置这个组件的一些属性。

1ae71b2a322c458fbc15e3c4e6fb9389.png
  • scaleType—给捕获的流设置缩放类型。可以使 CENTER_CROP 或者 CENTER_INSIDE
  • quality—设置捕获的媒体的质量。可以是 MAX,HIGH,MEDIUM 或者 LOW
  • pinchToZoomEnabled—一个布尔值,控制用户是否能够在 CameraView 内使用手指缩放视图
  • captureMode—设置捕获模式。可以是 IMAGE,VIDEO 或者 FIXED
  • lensFacing—设置镜头。可以是 FRONT,BACK 或者 NONE
  • flashMode—设置闪光灯模式。可以是 FRONT,BACK 或者 NONE

这些 xml 属性既可以在布局文件里设置,也可以在代码里设置。所以,如果你想提供 UI 控件控制上面这些属性 ,你可以使用 ClickListener 来设置这些属性。

既然我们是在 Activity 里布局的 CameraView,我们可以用 CameraView 的 bindToLifeCycle 方法将这个 View 与当前组件的生命周期绑定。

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ...view_camera.bindToLifecycle(this) }
}

前面所说的已经配置并且添加到我们的工程了,现在我们在 app 里有了一个准备好了的简单的 CameraView 来捕获媒体。需要说明的是,CameraView 不能被单独扩展来提供更多的功能。CameraView 的目标是提供一个简化的可以方便地以 View 的形式使用的相机实现。如果你想要实现更多的功能,你需要使用 CameraX Core 库,我们将在另一篇文章里聊到它。

如果你已经完成了上面的配置,那你应该能够打开相机并且在屏幕上看到预览了。CameraView 提供了一些当用户操作 UI 时我们可以触发的方法。

  • toggleCamera—切换设备正在使用的相机(例如在前置和后置相机之间切换)
  • enableTorch—开启闪光灯
  • setCameraByLensFacing—设置相机使用面向某个方向的镜头。可以是 LensFacing.Back 或者 LensFacing.Front。
  • hasCameraWithLensFacing—检测相机是否有与 LensFaing 值对应的镜头
  • focus—相机在指定矩形范围内对焦

当要使用拍照功能时,takePicture 方法可以从相机捕获图片。这里我们需要提供一个图片数据保存位置的文件引用,以及一个在图片成功保存或者出现错误时使用的 Listener。

camera_view.takePicture(File("some_file_path"),object : ImageCaptureUseCase.OnImageSavedListener {override fun onImageSaved(file: File) {// 处理被保存的图片}override fun onError(error: ImageCaptureUseCase.UseCaseError,message: String,throwable: Throwable?) {// 处理错误}})

当拍摄视频出现错误是,ImageCaptureUseCase.UseCaseError 将会给我们返回以下的某一错误状态:

  • UNKNOWN_ERROR
  • FILE_IO_ERROR

takePicture 还有另一种形式,这种形式只使用一个 OnImageCaptureListener 回调参数。这个回调用来监听图片被捕捉(或者出现了错误),然后开发者可以根据情况处理结果数据。前面的 takePicture 使用更简单,但这个 takePicture 提供了更多的灵活性。

camera_view.takePicture(object :     ImageCaptureUseCase.OnImageCapturedListener() {override fun onCaptureSuccess(image: ImageProxy, rotationDegrees: Int) {// 处理捕捉的图片}override fun onError(useCaseError: ImageCaptureUseCase.UseCaseError?, message: String?, cause: Throwable?) {// 处理图片捕获错误}})

我们可能也想使用 CameraView 来录视频。这时候我们需要使用 startRecoring() 方法—只需要传递一个用来保存结果的文件引用,以及一个 来处理操作结果(成果或者失败)的 listener

camera_view.startRecording(File("some_file_path"),object : VideoCaptureUseCase.OnVideoSavedListener {override fun onVideoSaved(file: File?) {// Handle video saved}override fun onError(error: VideoCaptureUseCase.UseCaseError?, message: String?, throwable: Throwable?) {// Handle video error}})

这里你可以看到,onVideSaved 方法给我们返回一个被保存的视频数据的文件实例。我们也有 onError 方法用来处理错误状态,在我们的 UI 上根据情况 作出对应的反馈。当拍摄视频导致错误时,VideoCaptureUseCase.UseCaseError 将会返回下面错误状态中的某一个:

  • UKNOWN_ERROR
  • ENCODER_ERROR
  • MUXER_ERROR
  • RECORDING_IN_PROGRESS

当用户希望停止拍摄视频时,我们只需要调用 stopRecording 方法让用例 知道我们希望停止拍摄视频:

camera_view.stopRecording()

最后,当我们使用 CameraView 完毕后,我们必须确保解绑相机,释放被用到的资源:

override fun onDestroyView() {super.onDestroyView()CameraX.unbindAll()
}

这篇文章我们了解了 CameraX 库以及 CameraView,学习如何使用以及使用它能够做什么。在安卓程序中实现相机功能,尤其是不需要使用高级的功能,这是一个很大的进步。你将会使用 CameraView 吗?如果你有任何想分享的想法或者问题,请一定要分享出来!

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

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

相关文章

一行语句让你的浏览器变成记事本

Jose Jesus Perez Aguinaga : One line browser notepad&#xff0c; 只需要在浏览器地址栏键入&#xff1a; data:text/html, <html contenteditable>转载于:https://www.cnblogs.com/fresky/archive/2013/01/31/2886837.html

c++opencv汉字分割_机器学习小白,还不快pick一下——【视觉与图像:阈值分割】...

“前言&#xff1a;安利Python来开发OpenCV的原因其实细心的小伙伴早在?【视觉与图像】PythonOpenCV教程入门篇就找到了想要的答案。(点蓝字即可打开)”今天周五了&#xff01;今天还不下雨&#xff01;&#xff01;今天又可以更新了&#xff01;&#xff01;&#xff01;先前…

python学习笔记--理解生成器

在学习python的时候&#xff0c;刚开始接触生成器&#xff08;generator&#xff09;这个概念的时候&#xff0c;其实还是不太能理解&#xff0c;感觉并没有完全掌握&#xff0c;今天看到这篇文章的时候&#xff0c;感觉对这个概念真的是有了进一步的了解&#xff0c;感觉生成器…

再不努力我就老了

借用李宇春歌里的一句话&#xff0c;再不疯狂我们就老了。。。再不努力青春就没了。。。 今天在浏览校内时&#xff0c;发现右下角滚动的照片中&#xff0c;竟有一张是关于自己的&#xff0c;那是自己5年前的照片&#xff0c;满脸的稚嫩&#xff0c;连自己都承认那时的自己真的…

mysql主键外键_MySQL主键和外键使用及说明

摘自网上一个经典的例子&#xff1a;大哥和小弟一、外键约束MySQL通过外键约束来保证表与表之间的数据的完整性和准确性。外键的使用条件&#xff1a;1.两个表必须是InnoDB表&#xff0c;MyISAM表暂时不支持外键(据说以后的版本有可能支持&#xff0c;但至少目前不支持)&#x…

python学习笔记--迭代器

转载自理解Python的迭代器 首先&#xff0c;廖雪峰老师的教程中解释了迭代器和生成器&#xff0c;这篇文章只是补充和我个人的总结。 什么是迭代 可以直接作用于for循环的对象统称为可迭代对象(Iterable)。 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterat…

【转载】周鸿祎:做产品体验先把自己切换到二傻子模式

我唯一能自吹的地方&#xff0c;就是本人在互联网里可能犯的错最多&#xff0c;挨的骂最多&#xff0c;然后也经历了很多失败&#xff0c;所以这样才有一些真实的感受。 建议大家把《定位》和《创新者的窘境》、《创新者的解答》这几本书放在身边反复读。你经历得越多&#xff…

mysql临时关闭索引功能_MYSQL中常用的强制性操作(例如强制索引)

mysql常用的hint对于经常使用oracle的朋友可能知道&#xff0c;oracle的hint功能种类很多&#xff0c;对于优化sql语句提供了很多方法。同样&#xff0c;在mysql里&#xff0c;也有类似的hint功能。下面介绍一些常用的。强制索引 FORCE INDEX复制代码代码如下:SELECT * FROM TA…

python学习--windows下安装Numpy包的错误:Unable to find vcvarsall.bat

今天在安装numpy包的时候&#xff0c;无论是通过pip install numpy 还是上网下载numpy包后安装都是出现问题&#xff1a;error: Unable to find vcvarsall.bat&#xff0c;于是百度了下&#xff0c;看到Windows下安装Python包(Numpy)的错误&#xff1a;Unabletofindvcvarsall.b…

使用多行sql字符串时,要注意不要忽略了空格

使用李刚老师编著的《疯狂Java讲义》&#xff08;第2版&#xff09;学习MySql数据库与JDBC编程&#xff08;使用Java 7 &#xff09;&#xff0c;其中第601页的ConnMySql.java 程序代码在Eclipse上运行&#xff0c;出现错误。 import java.sql.*; public class ConnMySql{publi…

Python学习笔记---理解zip()函数

转载自Python零碎知识(2):强大的zip 一、代码引导 首先看这一段代码&#xff1a; 1 >>> name(jack,beginman,sony,pcky)2 >>> age(2001,2003,2005,2000)3 >>> for a,n in zip(name,age):4 print a,n5 6 输出&#xff1a;7 jack 20018 beginma…

mysql8.0.11 安装顺序_mysql 8.0.11 安装步骤详解

本文为大家分享了mysql 8.0.11 安装步骤&#xff0c;供大家参考&#xff0c;具体内容如下第一步&#xff1a;下载安装包MYSQL官方下载地址&#xff1a;官方下载这里第一项是在线安装&#xff0c;第二项是离线包安装&#xff0c;我选择的是第二项(不用管你电脑是多少位的操作系统…

HDU1258 DFS

题意&#xff1a;求n个数中的某些数的和等于t&#xff0c;并输出 dfs 记录下已经输出过的&#xff0c;然后每次比较一下&#xff0c;这样就能避免重复 View Code 1 #include<stdio.h>2 #include<string.h>3 #include<stdlib.h>4 #include<algorithm>5…

Python 问题--encode、decode及shell中文输出

最近在使用python的时候&#xff0c;涉及到中文输出的时候经常会出现乱码的问题&#xff0c;所以就上网搜索了下&#xff0c;参考了1.Python字符串的encode与decode研究心得乱码问题解决方法&#xff1b; 2.python 中编码的再次学习 此外&#xff0c;更多详细字符编码的可以看…