这篇文章发布于 joebirch.co

https://joebirch.co/2019/05/15/exploring-camerax-on-android-camera-view/

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

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

配置 CameraX

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

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


首先在应用的 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}”"1.0.0-alpha01"// 添加 CameraX core “androidx.camera:camera-core:${camerax_version}”// 添加 CameraX Camera2 API 互操作支持implementation “androidx.camera:camera-camera2:${camerax_version}”

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

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

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

Camera View

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

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

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


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

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

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

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

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

当要使用拍照功能时,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?        ) {            // 处理错误        }    })    object : ImageCaptureUseCase.OnImageSavedListener {        override fun onImageSaved(file: File) {            // 处理被保存的图片        }        override fun onError(            error: ImageCaptureUseCase.UseCaseError,            message: String,            throwable: Throwable?        ) {            // 处理错误        }    })

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

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?        ) {            // 处理图片捕获错误        }    })    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        }    })    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 将会返回下面错误状态中的某一个:

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

camera_view.stopRecording().stopRecording()

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

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

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

我的下一篇文章将会写在 CameraX Core library 中发现的用例,请关注我,这样在文章发布时你能看到。

本文翻译自:
https://joebirch.co/2019/05/15/exploring-camerax-on-android-camera-view/

如有侵权,请联系本号删除。

推荐阅读
Kotlin:你必须要知道的 inline-noinline-crossinline
Flutter日历,可以自定义风格UI

编程·思维·职场
欢迎扫码关注

在看也是一种认可

探索 Android 平台的 CameraX相关推荐

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

    前言 如果你曾经用过 Android 的 Camera APIs,你可能已经感受到了,它们一直没有成为最容易实现的东西.最开始是 Camera API,然后又推荐使用 Camera2 API - 这个 ...

  2. Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.1 工程思路与难点

    回到目录 本文主要探讨搭建一款Android平台下美颜相机可能需要填的坑,内容会不断更新.. 相机框架 相机框架相对比较简单,现有的开源代码很多,可以很容易的实现拍照和录像的功能. 预览尺寸选择 预览 ...

  3. unity Android平台最佳效果探索(二)

    上一篇 unity Android平台最佳效果探索(一) 上篇写到了实现PC版的效果 继续 3.切换到Android平台后效果 直接切换后,不能运行,报错挺多. 原因: (1)Android平台不支持 ...

  4. Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.4 滤镜以及配套代码的制作方法

    Github项目地址 好久没有更新了,不行不行,怎么可以太监呢(`⌒´メ) 滤镜结构 滤镜主要是对于图像的处理,关于一款滤镜的制作方法可以看这里 既然是图像处理,那么滤镜的操作就主要是:卷积.像素映射 ...

  5. 美团外卖Android平台化的复用实践

    美团外卖平台化复用主要是指多端代码复用,正如美团外卖iOS多端复用的推动.支撑与思考文章所述,多端包含有两层意思:其一是相同业务的多入口,指美团外卖业务需要在美团外卖App(下文简称外卖App)和美团 ...

  6. android studio(1)---探索Android Studio

    探索 Android Studio Android Studio 是基于 IntelliJ IDEA 的官方 Android 应用开发集成开发环境 (IDE). 除了 IntelliJ 强大的代码编辑 ...

  7. 深入探索Android卡顿优化(下)

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. 在上篇文章中,笔者带领大家学习了卡顿优化分析方法与工具.自动化卡顿检测方案及优化这两块内容. ...

  8. 关于 Android 平台开发相关的有哪些推荐书籍?

    转自:http://www.zhihu.com/question/19579609 作者:Shan Huang 链接:http://www.zhihu.com/question/19579609/an ...

  9. 探索Android 9.0 Pie新特性变更

    北京时间 8 月 7 日上午,Google 正式发布 Android 9.0 正式版系统,并宣布系统版本 Android P 被正式命名为代号「Pie」. 目前,Google 已向全球 Pixel 设 ...

最新文章

  1. 视频光端机维护三大步骤
  2. 2.3)深度学习笔记:超参数调试、Batch正则化和程序框架
  3. 如何创建比C语言更快的编程语言?
  4. Online Judge System
  5. atitit.为什么笔记本跟个手机不能组装而pc可以
  6. ram计算机中术语,计算机术语 RAM ROM
  7. Java 算法刷题指南
  8. 人脸识别Demo解析C#
  9. handlersocket mysql_[原创]MongoDB、HandlerSocket和MySQL性能测试及其结果分析
  10. msm8953 uart配置
  11. z变换解差分方程例题_Z变换解差分方程的思考
  12. 王之泰201771010131《面向对象程序设计(java)》第一周学习总结
  13. 吴恩达预热新课!万字回顾机器学习!
  14. 动态iptables 防火墙
  15. code force 449 div2 C. Nephren gives a riddle
  16. 方差分析分类及SAS实现代码
  17. 黄金思维圈,养成透过现象看本质的能力
  18. 如何理解泰勒展开式,他有何用途?
  19. 认识频谱分析仪(1)- 原理及结构
  20. 如何配置重做日志高速缓存的大小

热门文章

  1. Allegro PCB Design GXL查看线长
  2. hutool导入导出excel
  3. mysql err 1677
  4. 如何做出一套完整的APP界面设计
  5. Oracle 恢复dmp文件到数据库表中 【数据系列 1】
  6. 用NSDateFormatter转换日期,得到大写字母的星期(SUN etc.)
  7. 用超级弹弓把飞船射上月球
  8. 计算机网络原理总结(英文版 第五版) Chapter3
  9. 小米笔记本我的世界java_小米笔记本Pro顶配版使用分享,买不买看完就知道了...
  10. 利用腾讯云服务器 FRP实现网络穿透 在本地搭建魔兽服务器