首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[译] Android 的多摄像头支持

[译] Android 的多摄像头支持

作者头像
Android 开发者
发布于 2018-09-30 03:21:13
发布于 2018-09-30 03:21:13
3.1K00
代码可运行
举报
文章被收录于专栏:Android 开发者Android 开发者
运行总次数:0
代码可运行

Android P 开始,添加了对逻辑多摄像头和 USB 摄像头的支持。这对 Android 开发者来说意味着什么?

多摄像头

一台设备有多个摄像头没什么新鲜的,但是直到现在,Android 设备仍然最多只有前后两个摄像头。如果你想要打开第一个摄像头,需要进行以下操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val cameraDevice = Camera.open(0)
复制代码

但是这些是比较简单的操作。如今多摄像头意味着前置或者后置有两个及两个以上的摄像头。有很多镜头可供选择!

Camera2 API

由于兼容性问题,尽管旧的 Camera API 已经被废弃很长时间,上述的代码仍然有效。但是随着生态系统的发展,需要更先进的相机功能。因此,Android 5.0(Lollipop)引进了 Camera2,适用于 API 21 及以上。用 Camera2 API 来打开第一个存在的摄像头代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val cameraManager = activity.getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraId = cameraManager.cameraIdList[0]
cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
    override fun onOpened(device: CameraDevice) {
        // Do something with `device`
    }
    override fun onDisconnected(device: CameraDevice) {
        device.close()
    }
    override fun onError(device: CameraDevice, error: Int) {
        onDisconnected(device)
    }
}, null)
复制代码

第一个并不是最好的选择

上述代码目前看起来没什么问题。如果我们所需要的只是一个能够打开第一个存在的摄像头的应用程序,那么它在大部分的 Android 手机上都有效。但是考虑到以下场景:

  • 如果设备没有摄像头,那么应用程序会崩溃。这看起来似乎不太可能,但是要知道 Android 运用在各种设备上,包括 Android Things、Android Wear 和 Android TV 等这些有数百万用户的设备。
  • 如果设备至少有一个后置摄像头,它将会映射到列表中的第一个摄像头。但是当应用程序运行在没有后置摄像头的设备上,比如 PixelBooks 或者其他一些 ChromeOS 的笔记本电脑,将会打开唯一一个前置摄像头。

那么我们应该怎么做?检查摄像头列表和摄像头特性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val cameraIdList = cameraManager.cameraIdList // may be empty
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
val cameraLensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
复制代码

变量 cameraLensFacing 有以下取值:

更多有关摄像头配置的信息,请查看文档.

合理的默认设置

根据应用程序的使用情况,我们希望默认打开特定的相机镜头配置(如果可以提供这样的功能)。比如,自拍应用程序很可能想要打开前置摄像头,而一款增强现实类的应用程序应该希望打开后置摄像头。我们可以将这样的一个逻辑包装成一个函数,它可以正确地处理上面提到的情况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fun getFirstCameraIdFacing(cameraManager: CameraManager,
                           facing: Int = CameraMetadata.LENS_FACING_BACK): String? {
    val cameraIds = cameraManager.cameraIdList
    // Iterate over the list of cameras and return the first one matching desired
    // lens-facing configuration
    cameraIds.forEach {
        val characteristics = cameraManager.getCameraCharacteristics(it)
        if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing) {
            return it
        }
    }
    // If no camera matched desired orientation, return the first one from the list
    return cameraIds.firstOrNull()
}
复制代码

切换摄像头

目前为止,我们讨论了如何基于应用程序的用途选择默认摄像头。很多相机应用程序还为用户提供切换摄像头的功能:

Google 相机应用中切换摄像头按钮

要实现这个功能,尝试从CameraManager.getCameraIdList()提供的列表中选择下一个摄像头,但是这并不是个好的方式。因为从 Android P 开始,我们将会看到在同样的情况下更多的设备有多个摄像头,甚至有通过 USB 连接的外部摄像头。如果我们想要提供给用户切换不同摄像头的 UI,建议(按照文档)是为每个可能的镜头配置选择第一个可用的摄像头。

尽管没有一个通用的逻辑可以用来选择下一个摄像头,但是下述代码适用于大部分情况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fun filterCameraIdsFacing(cameraIds: Array<String>, cameraManager: CameraManager,
                          facing: Int): List<String> {
    return cameraIds.filter {
        val characteristics = cameraManager.getCameraCharacteristics(it)
        characteristics.get(CameraCharacteristics.LENS_FACING) == facing
    }
}

fun getNextCameraId(cameraManager: CameraManager, currCameraId: String? = null): String? {
    // Get all front, back and external cameras in 3 separate lists
    val cameraIds = cameraManager.cameraIdList
    val backCameras = filterCameraIdsFacing(
            cameraIds, cameraManager, CameraMetadata.LENS_FACING_BACK)
    val frontCameras = filterCameraIdsFacing(
            cameraIds, cameraManager, CameraMetadata.LENS_FACING_FRONT)
    val externalCameras = filterCameraIdsFacing(
            cameraIds, cameraManager, CameraMetadata.LENS_FACING_EXTERNAL)

    // The recommended order of iteration is: all external, first back, first front
    val allCameras = (externalCameras + listOf(
            backCameras.firstOrNull(), frontCameras.firstOrNull())).filterNotNull()

    // Get the index of the currently selected camera in the list
    val cameraIndex = allCameras.indexOf(currCameraId)

    // The selected camera may not be on the list, for example it could be an
    // external camera that has been removed by the user
    return if (cameraIndex == -1) {
        // Return the first camera from the list
        allCameras.getOrNull(0)
    } else {
        // Return the next camera from the list, wrap around if necessary
        allCameras.getOrNull((cameraIndex + 1) % allCameras.size)
    }
}
复制代码

这看起来可能有点复杂,但是我们需要考虑到大量的有不同配置的设备。

兼容性行为

对于那些仍然在使用已经废弃的 Camera API 的应用程序,通过 Camera.getNumberOfCameras() 得到的摄像头的数量取决于 OEM 的实现。文档上是这样描述的:

如果系统中有逻辑多摄像头,为了保持应用程序的向后兼容性,这个方法仅为每个逻辑摄像头和底层的物理摄像头组公开一个摄像头。使用 camera2 API 去查看所有摄像头。

请仔细阅读 其余文档 获得更多信息。通常来说,类似的建议适用于:使用 Camera.getCameraInfo() API 查询所有的摄像头方向, 在用户切换摄像头时,仅仅只为每个可用的方向提供一个摄像头。

最佳实践

Android 运行在许多不同的设备上。你不应该假设你的应用程序总是在有一两个摄像头的传统的手持设备上运行,而是应该为你的应用程序选择最适合的摄像头。如果你不需要特定的摄像头,选择有所需默认配置的第一个摄像头。如果设备连接了外部摄像头,则可以合理的假设用户希望首先看到这些外部摄像头中的第一个。

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年09月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android适配多摄像头
从 Android P 开始,Android将添加对逻辑多摄像头和 USB 摄像头的支持。这意味着,除了前后两个摄像头外,Android手机的前置或者后置有两个及两个以上的摄像头。对此,对于Android开发者来说,就需要完成这方面的适配工作。
xiangzhihong
2022/11/30
1.1K0
Android Camera2 API 同时使用前后摄像头预览
不久前,我承担了从运行Android的设备的前后摄像头获取同步提要的任务。 像往常一样,我去了Stack Overflow,然后去了GitHub,然后去了其他博客,才意识到我可能独自一人。 难过的感觉吧?
字节流动
2022/09/26
3.4K0
Android Camera2 API 同时使用前后摄像头预览
从零开发一款相机APP 第六篇: Camera2相机 打开功能实现
本课程内容由 @公众号:小驰笔记出品,欢迎关注公众号,获取更多交流信息~
小驰行动派
2022/12/20
1.2K1
从零开发一款相机APP  第六篇: Camera2相机 打开功能实现
Android摄像头采集选Camera1还是Camera2?
好多开发者纠结,Android平台采集摄像头,到底是用Camera1还是Camera2?实际上,Camera1和Camera2分别对应相机API1和相机API2。Android 5.0开始,已经弃用了Camera API1,新平台重点开发Camera API2,Camera API1 会逐渐被淘汰。Camera API2 框架为应用提供更接近底层的相机控件,包括高效的零复制连拍/视频流以及曝光、增益、白平衡增益、颜色转换、去噪、锐化等方面的每帧控件。
音视频牛哥
2024/08/08
4020
Android摄像头采集选Camera1还是Camera2?
[译] 如何在 Android 开发中充分利用多摄像头 API
这篇博客是对我们的 Android 开发者峰会 2018 演讲 的补充,是与来自合作伙伴开发者团队中的 Vinit Modi、Android Camera PM 和 Emilie Roberts 合作完成的。查看我们之前在该系列中的文章,包括 相机枚举、相机拍摄会话和请求 和 同时使用多个摄像机流。
Android 开发者
2019/04/09
2.5K0
[译] 如何在 Android 开发中充分利用多摄像头 API
Android Camera2 Focus Distance
有一段时间,我一直在查找Camera Focus distance相关内容。网上也查找了不少资料,有时看别人提的问题以及回答,也能给自己带来不少的帮助,希望下面的内容也能帮助到有需要的小伙伴~
小驰行动派
2022/12/20
1.8K0
Camera2 采集
Camera2相比Camera1,使用起来要复杂一些,不过也节省了一些逻辑,比如可以自动处理角度问题。本篇就按照流程介绍下Camera2的简单使用,更多细节会后续介绍。
一只小虾米
2022/10/25
6500
Android AVDemo(7):视频采集,视频系列来了丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 iOS/Android 平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
1K0
Android AVDemo(7):视频采集,视频系列来了丨音视频工程示例
Android相机应用基本功能实现
Camera2引用了管道的概念将安卓设备和摄像头之间联通起来,系统向摄像头发送 Capture 请求,而摄像头会返回 CameraMetadata。这一切建立在一个叫作 CameraCaptureSession 的会话中。
Abalone
2022/07/14
2.2K1
Android相机应用基本功能实现
音视频直播技术--Android视频采集(Camera2)
今天为大家介绍一下如何在 Android 上进行视频采集。在 Android 系统下有两套 API 可以进行视频采集,它们是 Camera 和 Camera2 。Camera是以前老的 API ,从 Android 5.0(21)之后就已经放弃了。我今天主要给大家介绍一下如何使用 Camera2 进行视频的采集。原码可以在这里获取
音视频_李超
2020/04/02
2.2K0
这可能是全网关于Camera慢动作录像(SlowMotion)介绍最全的文章了
这是一篇关于慢动作录像(slowmotion)的文章,看完后相信你对慢动作录像不会再感到陌生了~
小驰行动派
2021/04/01
1.4K0
Android app小电筒(闪光灯)Torch demo,获取手电筒状态
二、在android 11 和android 8 真机上测试ok,点击按钮开关闪光灯。
IT工作者
2022/05/20
8960
这可能是全网关于Camera慢动作录像(SlowMotion)介绍最全的文章了
这是一篇关于慢动作录像(slowmotion)的文章,看完后相信你对慢动作录像不会再感到陌生了~
小驰行动派
2021/04/30
2.1K0
RenderDemo(2):用 OpenGL 渲染视频丨音视频工程示例
渲染是音视频技术栈相关的一个非常重要的方向,视频图像在设备上的展示、各种流行的视频特效都离不开渲染技术的支持。
关键帧
2023/02/14
1.5K0
RenderDemo(2):用 OpenGL 渲染视频丨音视频工程示例
相机10bit HDR录制
对于搭载Android13(T)及更高版本的设备来说,Android支持通过动态范围配置文件进行10bit相机输出
雪月清
2023/02/13
1K0
相机10bit HDR录制
Android流媒体开发之路一:Camera2采集摄像头原始数据并手动预览
  其实主要就是在不预览的情况下获取到摄像头原始数据,目的嘛,一是为了灵活性,方便随时开启关闭预览,二是为了以后可以直接对数据进行处理,三是为了其他程序开发做一些准备。于是实现一下几个功能:
hbstream
2018/05/11
3.3K0
Android流媒体开发之路一:Camera2采集摄像头原始数据并手动预览
使用Camera2获取depth图像
文章翻译自plluke的"在三星S10 5G上使用3D摄像头",想了解更多的小伙伴可以查看英文原文
雪月清
2022/07/11
1.3K0
使用Camera2获取depth图像
如何实现RTMP推送Android Camera2数据
在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。
音视频牛哥
2020/04/05
1.6K0
一篇文章带你了解Android 最新Camera框架
这篇文章主要分下面几点来展开讲解: 1)Android 最新Camera 整体框架; 2)Android Camera2 和HAL3 的基本了解; 3)Camera2 介绍; (本文所写的内容基于Android 9.0)
小驰行动派
2021/04/01
2K0
Android平台实现Camera2数据推送到RTMP服务器
在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。
音视频牛哥
2021/03/02
1.4K0
推荐阅读
相关推荐
Android适配多摄像头
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档