Android CameraX 如何实现广角/缩小

2024-04-05

我尝试使用以下方法为我的应用内相机实现广角选项CameraXapi 但遇到了一个问题 -CameraControl.setZoomRatio允许设置缩放范围ZoomState.getMinZoomRatio() and ZoomState.getMaxZoomRatio(),我在手机上测试过它minZoomRatio is 1.0f。同款手机支持缩小至0.5f在系统相机中。

当前片段我如何初始化相机:

private var camera: Camera? = null
private var imageCapture: ImageCapture? = null

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

    cameraProviderFuture.addListener({
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
                }

            imageCapture = ImageCapture.Builder()
                .setFlashMode(ImageCapture.FLASH_MODE_AUTO)
                .build()

            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                cameraProvider.unbindAll()

                camera = cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview, imageCapture
                )
                viewModel.onCameraStarted()
            } catch (exc: Exception) {
                Timber.e(exc)
            }
        },
        ContextCompat.getMainExecutor(this)
    )
}

当前捏合缩放实现:

val scaleGestureDetector = ScaleGestureDetector(this,
    object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScale(detector: ScaleGestureDetector): Boolean {
            val camera = camera ?: return false
            val zoomState = camera.cameraInfo.zoomState.value ?: return false
            val scale = zoomState.zoomRatio * detector.scaleFactor
            val finalScale =
                scale.coerceIn(MIN_ZOOM, MAX_ZOOM).coerceIn(zoomState.minZoomRatio, zoomState.maxZoomRatio)
            camera.cameraControl.setZoomRatio(finalScale)
            return true
        }
    })

binding.viewFinder.setOnTouchListener { view, event ->
    view.performClick()
    scaleGestureDetector.onTouchEvent(event)
    return@setOnTouchListener true
}

我的问题是可以使用广角相机(或实现0.5f缩放)使用CameraXapi,或者我是否必须使用重写整个实现Camera2.


正如问题下面的评论中所解释的,广角镜头相机(以及任何其他相机,例如,如果我们尝试实现变焦 x20,则为大变焦)是单独的相机,因此为了允许在普通相机和(例如)广角镜头相机之间切换,我们必须使用不同的相机选择器重新启动相机视图。我们如何重新启动它,这取决于我们(例如,在某些捏合后重新启动或通过切换相机的按钮重新启动)。

这是相机选择器,可以根据需要获取后置摄像头或广角镜头后置摄像头startCameraData.ultraWide param:

val cameraSelector = if (startCameraData.ultraWide) {
    CameraSelector.Builder()
        .addCameraFilter { cameraInfos ->
            // filter back cameras with minimum sensor pixel size
            val backCameras = cameraInfos.filterIsInstance<Camera2CameraInfoImpl>()
                .filter {
                    val pixelWidth = it.cameraCharacteristicsCompat.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE)?.width ?: 0
                    it.lensFacing == CameraSelector.LENS_FACING_BACK && pixelWidth >= 2000 // arbitrary number resolved empirically
                }  

            // try to find wide lens camera, if not present, default to general backCameras
            backCameras.minByOrNull {
                val focalLengths = it.cameraCharacteristicsCompat.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
                focalLengths?.getOrNull(0) ?: 0f
            }
                ?.let { listOf(it) } ?: backCameras
        }
        .build()
} else {
    CameraSelector.DEFAULT_BACK_CAMERA
}

Note:Camera2 api 可能无法让我们访问某些相机(具体取决于手机),但有时也会,除非应用程序包被 Google 列入白名单。例如打开相机应用程序(net.sourceforge.opencamera)已列入白名单,并且可以访问所有摄像机。 我通过将应用程序包更改为来测试这一点net.sourceforge.opencamera突然得到了 6 个相机 ID,而不是 3 个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android CameraX 如何实现广角/缩小 的相关文章

  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • 使用 Android 前台服务为 MediaPlayer 创建通知

    问题就在这里 我目前正在开发一个应用程序 该应用程序必须提供 A 广播播放器 来自 URL 的 AAC 直播 还有一个播客播放器 来自 URL 的 MP3 流 该应用程序必须能够在后台运行 Android 服务 并通过以下方式向用户公开持续
  • Android 应用程序在后台运行时保存数据

    目前我正在开发 xmmp 客户端 当应用程序位于前台时 该客户端工作得很好 但由于事实上 当应用程序处于后台时 我在 Application 类中保存了大量数据 复杂的 ArrayList 字符串和布尔值作为公共静态 每个字段都被垃圾收集
  • 如何将安卓手机从睡眠状态唤醒?

    如何以编程方式将 Android 手机从睡眠状态唤醒 挂起至内存 我不想获取任何唤醒锁 这意味着手机在禁用 CPU 的情况下进入 真正的 睡眠状态 我想我可以使用某种RTC 实时时钟 机制 有人有例子吗 Thanks 为了让Activity
  • 为什么将函数参数声明为最终的?

    我目前正在阅读 Sams 出版的 24 小时自学 Android 应用程序开发 一书 我对 Java Android 或其他方面还比较陌生 我对 ActionScript 3 有非常扎实的背景 它与 Java 有足够的相似之处 因此该语言本
  • 在自定义对象中创建时粘性服务不会重新启动

    我有一个具有绑定服务的单例对象 我希望它重新启动 当我从启动器启动应用程序时 单例对象将初始化并绑定到这个现有的服务实例 以下是在单例中创建和绑定服务的代码 public class MyState private static MySta
  • 如何从 SQLite 获取记录总数

    我正在尝试从 Sqlite DB 获取行的总数 以下是我想要做的代码片段 我不知道我在这里做错了什么 public static int getTotalCount Context context Cursor c null try c g
  • 获取 AlarmManager 中活动的 PendingIntents 列表

    我有办法获取活动列表PendingIntent在设备中 我开始工作AlarmManager我想看看我的PendingIntents 已正确创建和删除 也很高兴看到其他什么PendingIntent在那里 只是为了看看某些应用程序是否正在做一
  • TextView 之间有分隔线

    我正在尝试在 android studio 中创建以下布局 因为我对 android 东西还很陌生 所以我第一次尝试使用 LinearLayout 并认为这可能无法实现 现在我正在尝试使用RelativeLayout 我已经用颜色创建了这个
  • 在 Jetpack Compose 中启动动画矢量 Drawable

    我有一个动画矢量可绘制R drawable my anim 我想在 Jetpack Compose 中展示并开始 可绘制对象显示 渲染正确 但动画未启动 这是撰写视图 Composable fun SplashView Surface mo
  • ROOM迁移过程中如何处理索引信息

    CODE Entity tableName UserRepo indices Index value id unique true public class GitHubRepo PrimaryKey autoGenerate true p
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • Android相机意图:如何获取全尺寸照片?

    我正在使用意图来启动相机 Intent cameraIntent new Intent android provider MediaStore ACTION IMAGE CAPTURE getParent startActivityForR
  • Android Studio:无法启动守护进程

    当我尝试在 Android Studio 中导入 gradle 项目时 遇到以下错误 Unable to start the daemon process This problem might be caused by incorrect
  • 如何创建像谷歌位置历史记录一样的Android时间轴视图?

    我想设计像谷歌位置历史这样的用户界面 我必须为我正在使用的应用程序复制此 UIRecyclerView 每行都是水平的LinearLayout其中包含右侧的图标 线条和视图 该线是一个FrameLayout具有圆形背景和半透明圆圈Views
  • 在 Android 上按下电源按钮时,如何防止先调用 onDestroy() 再调用 onCreate()

    我正在记录每个 onCreate 和 onDestroy 调用 我发现 一旦我单击 Android 上的电源按钮 以及模拟器上的电源按钮 我的活动中就会拨打电话 gt onDestroy gt onCreate 这会杀死我的游戏 然后立即从
  • Android 如何聚焦当前位置

    您好 我有一个 Android 应用程序 可以在谷歌地图上找到您的位置 但是当我启动该应用程序时 它从非洲开始 而不是在我当前的城市 国家 位置等 我已经在developer android com上检查了信息与位置问题有关 但问题仍然存在
  • 如何将图像从 Android 应用程序上传到网络服务器的特定文件夹中

    如何将图像从 android 移动到 Web 服务器上的指定文件夹 这是我的安卓代码 package com example bitmaptest import java io ByteArrayOutputStream import ja
  • 在 Android 中,如何将字符串从 Activity 传递到 Service?

    任何人都可以告诉如何将字符串或整数从活动传递到服务 我试图传递一个整数 setpossition 4 但它不需要 启动时总是需要 0 Service 我不知道为什么我不能通过使用 Service 实例从 Activity 进行操作 publ
  • 找到 Android 浏览器中使用的 webkit 版本?

    有没有办法知道某些特定手机上的 Android 浏览器使用的是哪个版本的 webkit 软件 如果有一个您可以浏览以获取该信息的 URL 那就太好了 但任何其他方式也很好 如果你知道 webkit 版本 你就知道 html5 支持多少 至少

随机推荐