0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深入了解CameraX 1.1版本的视频拍摄功能

谷歌开发者 来源:谷歌开发者 作者:谷歌开发者 2022-01-25 12:01 次阅读

CameraX 是一个 Jetpack 支持库,旨在帮助您简化相机应用的开发工作。它提供一致且易用的 API 接口,适用于大多数 Android 设备,并可向后兼容至 Android 5.0 (API 级别 21)。我们将在本文中介绍 CameraX 1.1 的多项功能,比如视频功能。

CameraX 概览

CameraX 是一个为了简化编写相机应用而设计的支持库,它所提供的高级 API 可以让开发者专注于和用户交互而非相机的内部实现。我们一直在探索并修复其背后复杂的兼容性问题,让每个新版本都得以在更多的设备上稳定运行。

何时使用 CameraX 或 Camera2,这取决于您期望更快的开发速度或是想要更高的自定义程度。

CameraX 可以很方便地实现普通照片视频的拍摄功能,而 Camera2 则可以对拍摄流程进行特殊控制,例如实现多重曝光或全手动捕获;

CameraX 旨在消除不同设备间的差异并在不同设备上进行了测试,而 Camera2 则需要应用来管理不同设备间的差异并测试其行为;

CameraX 提升了代码开发速度,让您更专注于用户界面和体验流程,而 Camera2 则用于更深入地开发以创造基于相机的定制功能;

CameraX 发布新版本频繁,而 Camera2 则随着 Android 的版本而更新;

CameraX 可以在您不熟悉相机的情况下也能够进行开发,而 Camera2 则需要您对相机的专业知识有更深层次的了解。

CameraX 基于主要的使用场景来构建,比如实时预览相机、检索缓冲区以进行分析和拍摄照片,在 CameraX 1.1 版本中还加入了视频拍摄功能。我们来看一个简单的 CameraX 示例:

fun bindPreview(cameraProvider : ProcessCameraProvider) {    // 使用 CameraX 创建 Preview 用例    var preview : Preview = Preview.Builder().build()
    // 创建 cameraSelector,它会在设备上搜索所需的相机    var cameraSelector : CameraSelector = CameraSelector.Builder()        // 在本例中,我们选择搜索后置相机        .requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
    // 从 CameraX 的 CameraView 包中获取 previewView 的句柄    // 利用此方法可以轻松的将相机内容添加到视图上    preview.setSurfaceProvider(previewView.getSurfaceProvider())
    // 将 preview 与其生命周期绑定    var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner,                                cameraSelector, preview)}

△ CameraX 代码示例

CameraX 是生命周期感知型组件,这意味着它将自动处理应用的生命周期事件来实现开始、停止、暂停和恢复。现在,应用启动时屏幕上便会显示实时预览。

我们已于 2021 年 5 月发布了 1.0 稳定版本,目前正在开发 1.1 Alpha 版本并且很快将会进入 Beta 阶段。并且我们一如既往地不断为新增设备推出兼容性修复程序,例如 1.0.1 和 1.0.2。

在 CameraX 1.1 版本中我们新增了开发者呼声很高的功能,具体而言,在本文中我们将重点介绍:

视频拍摄

YUV 到 RGB 的转换

Beta 版 Extensions API

一些需要了解的其它功能

视频拍摄

在 CameraX 1.1 版本中我们加入了视频拍摄功能,视频拍摄 API (尚处于 Alpha 阶段,细节可能会发生变化,但整体结构基本会保持不变) 提供了录制到文件等基本功能、可自动适配每台设备的 Quality Setting API,以及 Lifecycle Management API。接下来我们先来了解如何设定视频拍摄功能,代码示例如下:

// 创建 Recorderval recorder = Recorder.Builder()                       // 我们可以在此处使用 setQualitySelector 设置视频质量                       .setQualitySelector(...)                       .build()
// 使用新创建的 Recorder 创建 VideoCaptureval videoCapture = VideoCapture.withOutput(recorder)
// 将其与生命周期绑定cameraProvider.bindToLifecycle(    this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)
// 设定 VideoRecordEvent 监听器val videoRecordEventListener = Consumer{    when (it) {        is VideoRecordEvent.Start -> {}        is VideoRecordEvent.Finalize -> {}        is VideoRecordEvent.Status -> {            // status 事件将会在录制时持续更新            val stats: RecordingStats = it.recordingStats            // RecordingStats 中包含录制文件的尺寸和时长        }        is VideoRecordEvent.Pause -> {}        is VideoRecordEvent.Resume -> {}
// 指定输出val mediaStoreOutput = MediaStoreOutputOptions.Builder(this.contentResolver,        MediaStore.Video.Media.EXTERNAL_CONTENT_URI)    .setContentValues(contentValues)    .build()
// 准备录制val activeRecording = videoCapture.output.prepareRecording(this, mediaStoreOutput)    // 关联事件监听器    .withEventListener(ContextCompat.getMainExecutor(this), videoRecordEventListener)    // 启用音频 (前提是此应用已获得音频权限)    .withAudioEnabled()    // 开始录制.start()

△ 视频拍摄示例

videoCapture 会在应用启动时就绪,应用可以使用 videoRecordEventListener 响应开始、结束、暂停和恢复等拍摄事件,其中 Status 事件会提供包括文件大小和持续时间的 RecordingStats。视频拍摄可以输出到 File、FileDescriptor 或 MediaStore,在本例中我们选择 MediaStore。如果选择启用音频,则需要此应用已经获得音频权限。调用 start() 开始录制为我们提供了 activeRecording 句柄,它可以用来暂停、恢复或停止录制。您可以在 1.1 版本中试用这些 API。

YUV 至 RGB 的转换

另一个呼声很高的功能是 YUV 到 RGB 的转换,我们来了解一下此功能。

相机通常以 YUV420 格式生成数据,其中包括明亮度 (Luminance, Y)、色度 (Chroma, U, V) 和一些填充字节以将各行与有效的内存步幅对齐。但是这种格式的图像处理起来可能很麻烦,而现在 CameraX 可以将 ImageAnalysis 的输出转换为大家更熟悉的 RGBA 以方便处理。接下来我们看一个示例:

val imageAnalysis = ImageAnalysis.Builder()        .setTargetResolution(Size(1280, 720))        .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build()

△ 从 ImageAnalysis 获取 RGB 输出

在示例代码中,我们创建了 ImageAnalysis 实例,为图像缓冲区指定了所需的分辨率和背压策略,并调用新的 setOutputImageFormat 方法以请求 RGBA 8888 格式的输出。现在,ImageAnalysis 输出的帧为 RGBA 8888 数据而不再是 YUV 格式。

CameraX 中 YUV 到 RGB 的转换基于 libyuv。此外,在 CameraX 1.1 版本中数据本身可以转换到目标分辨率。在中端设备上对图像大小为 640x480 至 1080p 的数据进行转换大约需要 5~10 毫秒,具体性能因设备而异。此外 APK 会略微增加 50KB 左右。

修复单像素漂移

YUV 转换还修复了部分设备上存在的单像素漂移问题。在这些设备上,YUV 输出经过桶形移位一个像素,导致最右边的一列数据出现在图像的左边缘。在已知会发生这种情况的设备上,进行 YUV 到 RGB 的转换及输出 YUV 或 RGB 都会被修复,并且 CameraX 将会持续对更多有需要的设备进行修复。

CameraX Extensions API

相机特效在 CameraX 1.1 中的 CameraX Extensions API 可以更为充分地发挥设备强大的功能。

CameraX Extensions 包括一些最常见的内置相机特效:

BOKEH (焦外虚化): 在人像模式下拍摄照片时,让前景人物更清晰。

HDR (高动态范围): 拍照时使用不同的自动曝光 (AE) 配置,以获得最佳效果。

NIGHT (夜间): 在低照度环境下 (通常是在夜间) 捕获最佳静态图像。

FACE RETOUCH (脸部照片修复): 拍摄静态图像时,修饰脸部肤色、轮廓等。

AUTO (自动): 根据周围的景色自动调整最终图像。

我们来看看如何使用 CameraX Extensions API:

// 获取后置相机列表val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
// 检查所有的后置相机中是否有支持焦外虚化if (extensionsManager.isExtensionAvailable(    cameraProvider,    cameraSelector,    ExtensionMode.BOKEH)) {    // 创建扩展 cameraSelector,我们提供了相机并指定焦外虚化模式    // 它将开始在后台搜索支持焦外虚化的后置相机    val bokehCameraSelector = extensionsManager.getExtensionCameraSelector(        cameraProvider,        cameraSelector,        ExtensionMode.BOKEH    )
    // 创建 imageCapture 和 preview    val imageCapture = ImageCapture.Builder().builder()    val preview = Preview.Builder().build()
    // 使用 bokehCameraSelector 将它们绑定到生命周期    cameraProvider.bindToLifecycle(lifecycleOwner,        bokehCameraSelector,        imageCapture,        preview    )}
△ 以 BOKEH 效果捕捉并预览图像

在上面的例子中,imageCapture 输出的图像将会具有焦外虚化效果,如果设备支持的话,preview 也将预览焦外虚化效果。

曝光补偿

CameraX 1.1 中还添加了曝光补偿 API,此功能可以帮助用户更好地捕捉过度曝光或者曝光不足的区域。

如图所示我们所处的场景窗外很明亮而室内很昏暗,此时则可以调整曝光补偿来更好地捕捉明亮的室外或昏暗的室内场景。我们来看一个例子:

// 创建变量来跟踪 exposureIndex 值var exposureIndex = 0// 使用 cameraSelector 将 imageCapture 和 preview 绑定到生命周期val camera = cameraProvider.bindToLifecycle(    lifecycleOwner,    getCameraSelector(),    preview,    imageCapture) // 为视图中的按钮添加点击事件evButton.setOnclickListener {     // 检查有效的范围以防止可能的异常    val range = camera.cameraInfo.exposureState.exposureCompensationRange     if (range.contains(exposureIndex + 1)) {        // 调用 camera.cameraControl 的 setExposureCompenstation() 方法来设置曝光补偿        camera.cameraControl.setExposureCompenstation(++exposureIndex)        // 使用 exposureCompensationStep 来实现从 index 到 EV 到转换        val ev = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex        Log.i("CameraXLog", "EV: $ev")    }}

△ 通过按钮调整曝光

其中 exposureIndex 是一个与设备无关的数字,它将以硬件允许的最小步长递增或递减曝光值,因此可以在不同的设备上以类似的方式运作。如果您想向用户展示 EV 值,可以获取 exposureCompensationStep 来实现转换。

平滑缩放

在 CameraX 1.1 中,我们还增加了平滑缩放功能。有一些设备有包括广角和长焦在内的多个镜头,CameraX 可以检测这些设备是否支持 SMOOTH_ZOOM 框架,在受支持的设备上使用 CameraX 的缩放控件时,会自动使用所有的相机来实现更大的缩放范围。如果您已经在使用这个缩放控件,那当您使用 1.1 版本进行编译时,您的应用应该就可以访问这些设备上的所有相机。

CameraX 1.1 的更多功能

接下来介绍我们在 1.1 中添加的更多功能。

CameraState API 现在可以提供诸如另一个应用正在使用相机或者正处于勿扰模式等更多有关相机状态的信息,使得应用能够围绕不同的相机时间来设计更好的界面和用户体验流程。Image Analysis 现在可以提供超过 1080p 的图像。Logging API 可以更详细的调试日志并改善了错误报告。Coordinate Transformation API 可以将不同用例间的坐标关联起来,如果您在 imageAnalysis 缓冲区中定位了兴趣点,便可以方便地在图像捕捉的输出或预览中轻松找到它。您可以使用 CameraFilter API 来指定详细的规则以选择合适的相机。如果应用只需要前置或者后置相机,可以使用 AvailableCamerasLimiter 来加快启动时间。CameraControllerInfo 中可提供相机功能的更多详细信息。

设备兼容性

CameraX 会持续关注设备兼容性,以便应用在众多设备上都能够良好运行。我们修复了很多诸如图像拉伸、缩放不正确、图像颠倒及关闭相机时意外输出了绿色图形等问题。每个 CameraX 的发布版本或补丁版本中都会添加此类修复,最新的稳定版为 1.0.2。

您可以在版本记录中看到每个版本中的详细变更,还可以在问题跟踪器中看已经修复的问题。

希望对 CameraX 1.1 版本的简要介绍对大家有所帮助,非常期待看到大家使用 CameraX 构建的功能!

原文标题:CameraX 1.1 有哪些新的特性发布?

文章出处:【微信公众号:谷歌开发者】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3911

    浏览量

    126990
  • 相机
    +关注

    关注

    4

    文章

    1331

    浏览量

    53418
  • 设备
    +关注

    关注

    2

    文章

    4431

    浏览量

    70478

原文标题:CameraX 1.1 有哪些新的特性发布?

文章出处:【微信号:Google_Developers,微信公众号:谷歌开发者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    深入了解示波器

    深入了解示波器
    发表于 11-14 22:32

    专家开讲:深入了解电池技术 ──Part 1

    。笔者不会一一详细介绍所有的电池技术,只选择一些常见或是值得认识的;而在接下来的专栏里,笔者将开始介绍电池分类、常见规格以及专业术语,如果你有特别想知道的电池技术,欢迎留言!扩展阅读:专家开讲:深入了解
    发表于 08-18 09:33

    专家开讲:深入了解电池技术──Part 3

    资深工程师 Ivan Cowie 的「深入了解电池技术」专栏Part 3来啰!这次要介绍的是铅酸电池(lead-acidbatteries)技术。铅酸电池是在1859年由法国物理学家Gaston
    发表于 08-18 09:37

    单片机的深入了解

    项目名称:单片机的深入了解!项目是否开源:否申请开发板数量:1 块申请人团队介绍:我们团队由五个人组成,我们打算开始着手单片机的程序改编,设计一些比较特殊新颖的东西!希望给以支持!
    发表于 10-12 20:00

    深入了解LabVIEW FPGA资料分享

    深入了解LabVIEW FPGA
    发表于 05-27 08:35

    Zigbee各版本对比,让你深入了解

    Zigbee各版本对比,让你深入了解ZigBee是基于IEEE802.15.4标准的低功耗局域网协议。根据国际标准规定,ZigBee技术是一种短距离、低功耗的无线通信技术。这一名称(又称紫蜂协议
    发表于 02-29 11:24

    深入了解示波器(入门手册),pdf版本

    本帖最后由 alpha007 于 2016-10-24 14:49 编辑 深入了解示波器(入门手册),pdf版本
    发表于 07-07 09:53

    示波器的深入了解

    示波器的深入了解 引言自然界运行着各种形式的正弦波,比如海浪、地震、声波、爆破、空气中传播的声音,或者身体运转的自然节律。物理世界里,能
    发表于 11-04 11:53 52次下载
    示波器的<b class='flag-5'>深入了解</b>

    深入了解示波器入门手册

    深入了解示波器入门手册
    发表于 03-27 17:43 241次下载
    <b class='flag-5'>深入了解</b>示波器入门手册

    深入了解电路噪声的那些事

    模拟电子的相关知识学习教材资料——深入了解电路噪声的那些事
    发表于 09-27 15:19 0次下载

    深入了解电感与磁珠的异同

    模拟电子的相关知识学习教材资料——深入了解电感与磁珠的异同
    发表于 09-27 15:19 0次下载

    深入了解Room 2.4.0版本的新增功能

    对 Room 有着更高的期望,我们也致力于此,在 2.2.0 - 2.4.0 版本中发布了很多开发者们期待的新功能!包括自动化迁移,关系查询方法以及支持 Kotlin Symbol Processing (KSP) 等等。下面我们就来逐一介绍这些新
    的头像 发表于 01-25 11:07 2791次阅读

    带你深入了解示波器

    带你深入了解示波器
    发表于 02-07 14:26 19次下载

    深入了解安全光栅

    深入了解安全光栅
    的头像 发表于 06-25 13:53 1123次阅读
    <b class='flag-5'>深入了解</b>安全光栅

    深入了解 GaN 技术

    深入了解 GaN 技术
    的头像 发表于 12-06 17:28 6007次阅读
    <b class='flag-5'>深入了解</b> GaN 技术