CameraX 库如何打开/关闭手电筒?

Posted

技术标签:

【中文标题】CameraX 库如何打开/关闭手电筒?【英文标题】:How does CameraX library can turn ON/OFF the torch? 【发布时间】:2019-10-05 12:20:33 【问题描述】:

我正在开发一项功能,可以将手电筒切换到开/关状态。几天前,我们在 io2019 中看到了来自 Google 的新库。我想出了一个主意,为什么不使用它。

一段时间后,我看不到任何可能使用图书馆中唯一的手电筒。

即使在官方文档中,我也找不到任何适合我的信息,而且他们的示例应用程序也不必处理我的情况。

您有什么容易实现的想法,或者您知道如何使用 CameraX 来实现吗?

我担心使用相机或相机2,因为要粘贴的代码量很糟糕。

链接

[1]https://developer.android.com/training/camerax

[2]https://proandroiddev.com/android-camerax-preview-analyze-capture-1b3f403a9395

[3]https://github.com/android/camera/tree/master/CameraXBasic

[4]https://github.com/android/camera/tree/master/CameraXBasic

CameraX 是一个 Android Jetpack 库,旨在简化相机开发。

【问题讨论】:

【参考方案1】:
androidx.camera:camera-core:1.0.0-alpha10

你可以用这个检查手电筒是否可用:

val camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview, imageAnalyzer)

camera.cameraInfo.hasFlashUnit()

您可以通过以下方式启用手电筒:

camera.cameraControl.enableTorch(true)

【讨论】:

非常感谢!我在答案中输入了最新的语法。【参考方案2】:

这是您可以做到的一种方式(Kotlin)。如果有更好的方法请告诉我。以下代码假设您已经在设备上建立了闪存的可用性。

声明一个 flashMode 变量

private var flashMode: Int = ImageCapture.FLASH_MODE_OFF

在 updateCameraUI 中设置监听器

controls.findViewById<ImageButton>(R.id.flash_button).setOnClickListener 
    when (flashMode) 
        ImageCapture.FLASH_MODE_OFF ->
            flashMode = ImageCapture.FLASH_MODE_ON
        ImageCapture.FLASH_MODE_ON ->
            flashMode = ImageCapture.FLASH_MODE_AUTO
        ImageCapture.FLASH_MODE_AUTO ->
            flashMode = ImageCapture.FLASH_MODE_OFF
    
    // Re-bind use cases to include changes
    bindCameraUseCases()

在 bindCameraUseCases 中设置闪光模式

            imageCapture = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                .setTargetAspectRatio(screenAspectRatio)
                .setTargetResolution(screenSize)
                .setTargetRotation(rotation)
                .setFlashMode(flashMode)
                .build()

【讨论】:

有帮助...谢谢【参考方案3】:

2021 语法。

使用 Java 在 Android 上打开 Torch。

您的典型相机预览代码(例如来自 google 示例)通常以如下方式结束:

cameraProvider.bindToLifecycle((LifecycleOwner)this,
                 cameraSelector, imageAnalysis, preview);

打开/关闭手电筒...

Camera cam = cameraProvider.bindToLifecycle((LifecycleOwner)this,
                 cameraSelector, imageAnalysis, preview);

if ( cam.getCameraInfo().hasFlashUnit() ) 
    cam.getCameraControl().enableTorch(true); // or false

就是这样!

【讨论】:

编辑 - 干杯,不要删除有利于搜索引擎的短语 对于任何只想打开闪光灯的人,您仍然需要相机权限才能使其工作,并且至少需要 1 个用例才能绑定到 cameraProvider。【参考方案4】:

我无法发表评论,所以我正在回答以扩展 yevhen_69 的回答。

设置 enabledTorch(true) 对我也不起作用,但是我发现我必须在调用 CameraX.bindToLifecycle 之后设置 enableTorch(true)

val previewConfig = PreviewConfig.Builder().apply 
        setLensFacing(lensFacing)
        // Any setup
        setTargetRotation(viewFinder.display.rotation)
.build()

val preview = Preview(previewConfig)

CameraX.bindToLifecycle(this, preview)
preview.enableTorch(true)

不过,附带说明一下,CameraX 仍处于 Alpha 阶段,因此仍建议使用 Camera2 API。

【讨论】:

【参考方案5】:
// CameraX
def cameraXVersion = "1.0.0-beta07"
implementation "androidx.camera:camera-camera2:$cameraXVersion"
implementation "androidx.camera:camera-lifecycle:$cameraXVersion"
implementation "androidx.camera:camera-view:1.0.0-alpha14"

    private fun initializeFlashButton() = with(binding) 
        camera?.apply 
            if (cameraInfo.hasFlashUnit()) 
                flashButton.setOnClickListener 
                    flashButton.visibility = View.VISIBLE
                    cameraControl.enableTorch(cameraInfo.torchState.value == TorchState.OFF)
                
             else 
                flashButton.visibility = View.GONE
            

            cameraInfo.torchState.observe(viewLifecycleOwner)  torchState ->
                if (torchState == TorchState.OFF) 
                    flashButton.setImageResource(R.drawable.ic_flash)
                 else 
                    flashButton.setImageResource(R.drawable.ic_flash_active)
                
            
        
    

初始化camera对象后需要执行该方法

【讨论】:

出色的答案。感谢您利用观察火炬状态。不过可以使用更多的解释。仍然是一个很好的答案。【参考方案6】:

2022 语法

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


val camera = cameraProvider.bindToLifecycle(
             this, cameraSelector, preview, imageCapture, imageAnalyzer)
                
if (camera.cameraInfo.hasFlashUnit()) 
     camera.cameraControl.enableTorch(true)


【讨论】:

【参考方案7】:
val previewConfig = PreviewConfig.Builder().apply 
            setLensFacing(lensFacing)
            // Any setup
            setTargetRotation(viewFinder.display.rotation)
.build()

val preview = Preview(previewConfig)

preview.enableTorch(true)

【讨论】:

抱歉,enableTorch 似乎无法在我使用 Android 8.0 的华为 P10 Lite 上运行。预览工作正常,但似乎它并不关心 enableTorch(true)。 ¯_(ツ)_/¯ 有什么想法吗? enableTorch 不再是Preview 类的方法;见developer.android.com/reference/androidx/camera/core/…【参考方案8】:
androidx.camera:camera-core:1.0.0-alpha06

CameraX 新版本提供了这些功能。 CameraInfo 添加了检查 Flash Available 和 Sensor Rotation APIs,参考这个link

try 
    CameraInfo cameraInfo = CameraX.getCameraInfo(currentCameraLensFacing);
    LiveData<Boolean> isFlashAvailable = cameraInfo.isFlashAvailable();
    flashToggle.setVisibility(isFlashAvailable.getValue() ? View.VISIBLE : View.INVISIBLE);
 catch (CameraInfoUnavailableException e) 
    Log.w(TAG, "Cannot get flash available information", e);
    flashToggle.setVisibility(View.VISIBLE);

【讨论】:

你正在使用的CameraX这个类在哪里?我认为 CameraX 是一个库而不是一个类,我找不到任何静态方法 CameraX.getCameraInfo 就像你在这里所说的那样。另外,这段代码 sn-p 只会检查 flash 状态并根据 flash 状态设置切换的可见性,它实际上不会设置 flash 状态 这是cameraX处于alpha阶段的例子,在最新版本中可能会移除这个类。【参考方案9】:

使用CameraControl 作为全局变量,使用布尔值表示关闭和打开。

 lateinit var cameraControl: CameraControl
 private var flashFlag: Boolean = true

通过点击监听器关闭和打开。

flashFlag = !flashFlag
cameraControl.enableTorch(flashFlag)

在这个功能中我已经启动了相机预览。

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

        cameraProviderFuture.addListener(
            // Used to bind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Preview
            val preview = Preview.Builder()
                .build()
                .also 
                    it.setSurfaceProvider(binding.cameraView.surfaceProvider)
                

            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try 
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                val camera = cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview
                )
                cameraControl = camera.cameraControl
                cameraControl.enableTorch(flashFlag)

             catch (exc: Exception) 
                Log.e(TAG, "Use case binding failed", exc)
            

        , ContextCompat.getMainExecutor(this))
    

【讨论】:

什么是绑定? 那是viewBinding,你可以在这里调用你的cameraView。【参考方案10】:

您可以在Preview 对象上启用手电筒。 https://developer.android.com/reference/androidx/camera/core/Preview.html#enableTorch(boolean)

您可以在ImageCapture 对象或关联的配置生成器上设置闪光模式(开/关/自动)。 https://developer.android.com/reference/androidx/camera/core/ImageCapture.html#setFlashMode(androidx.camera.core.FlashMode) https://developer.android.com/reference/androidx/camera/core/ImageCaptureConfig.Builder.html#setFlashMode(androidx.camera.core.FlashMode)

【讨论】:

看起来该方法 enableTorch 现在已从 API 中删除

以上是关于CameraX 库如何打开/关闭手电筒?的主要内容,如果未能解决你的问题,请参考以下文章

设备屏幕关闭时如何打开手电筒?

使用相机时如何打开/关闭手电筒?

在 zxing 片段库中打开/关闭手电筒

如何打开安卓设备的前置手电筒(不是后置手电筒)

如何在 Android N 中打开设备手电筒?

如何使用 cameraX 在相机应用程序中实现 FlashToggle 按钮?