CameraX - 在 imageCapture.takePicture 后防止关闭手电筒或闪光灯。

3
我正在开发一个应用程序,其中需要在摄像头工作时保持手电筒的开启状态,同时还需要在不关闭手电筒的情况下拍照。我需要这个功能来提高用户体验。
但是每次拍照时,手电筒都会关闭,我的问题是如何防止这种情况发生?
class CameraFragment : Fragment()  {
    private lateinit var cameraExecutor: ExecutorService
    
    private var cameraProvider: ProcessCameraProvider? = null
    private var preview: Preview? = null
    private var imageCapture: ImageCapture? = null
    private var imageAnalysis: ImageAnalysis? = null
    private var camera: Camera? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        cameraExecutor = Executors.newSingleThreadExecutor()

        if (allPermissionsGranted()) {
            startCamera()
        } else {
            ActivityCompat.requestPermissions(requireActivity(),
                REQUIRED_PERMISSIONS,
                REQUEST_CODE_PERMISSIONS
            )
        }
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
        cameraProviderFuture.addListener({
            cameraProvider = cameraProviderFuture.get()
            bindCameraUseCases()
        }, ContextCompat.getMainExecutor(requireContext()))
    }

    private fun bindCameraUseCases() {

        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()

        val rotation = binding.viewFinder.display.rotation

        preview = Preview.Builder()
            .setTargetRotation(rotation)
            .build()

        imageCapture = ImageCapture.Builder()
            .setTargetRotation(rotation)
            .setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY)
            .build()

        imageAnalysis = ImageAnalysis.Builder()
            .setTargetRotation(rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
            .build()

        imageAnalysis?.setAnalyzer(cameraExecutor) {
            // Some analysis
        }

        cameraProvider?.unbindAll()

        try {
            camera = cameraProvider?.bindToLifecycle(
                this@CameraFragment,
                cameraSelector,
                preview,
                imageCapture,
                imageAnalysis
            )

            // OPEN FLASH
            openFlash()

            preview?.setSurfaceProvider(binding.viewFinder.surfaceProvider)
        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }
    }

    private fun takePhoto() {
        val imageCapture = imageCapture ?: return

        imageCapture.takePicture(cameraExecutor, object : ImageCapture.OnImageCapturedCallback() {
            override fun onCaptureSuccess(image: ImageProxy) {
                super.onCaptureSuccess(image)
                // image process
            }

            override fun onError(exception: ImageCaptureException) {
                super.onError(exception)
                println("ERROR")
            }
        })
    }

    private fun openFlash() {
        if (camera?.cameraInfo?.hasFlashUnit() == true) {
            camera?.cameraControl?.enableTorch(true)
        }
    }

    private fun closeFlash() {
        if (camera?.cameraInfo?.hasFlashUnit() == true) {
            camera?.cameraControl?.enableTorch(false)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

    override fun onResume() {
        super.onResume()
        openFlash()
    }

    override fun onPause() {
        super.onPause()
        closeFlash()
    }

    companion object {
        private const val TAG = "Camera"
        //  private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
        private const val REQUEST_CODE_PERMISSIONS = 10

        private val REQUIRED_PERMISSIONS = mutableListOf (
            Manifest.permission.CAMERA
        ).toTypedArray()
    }
}

拍照时不应关闭手电筒。如果你有一个最小可复现的例子,我可以看一下。 - Xi 张熹
拍照时不应该关闭手电筒。如果你有一个最小可重现的例子,我可以帮你看一下。 - undefined
也许是小米设备的问题,但最终我还是选择了使用camera2来完成我的项目。那正是我用于cameraX的代码。我注意到即使在camera2中闪光灯也会关闭,但我成功解决了这个问题。@Xi张熹 - kallis
2个回答

0
解决方案1:
我认为由于onPause()生命周期方法,当片段失去焦点时手电筒会关闭。
尝试在onPause()生命周期方法中删除closeFlash()行。
解决方案2:
尝试在takePhoto()方法中调用openFlash()方法。
private fun takePhoto() {
        val imageCapture = imageCapture ?: return

        imageCapture.takePicture(cameraExecutor, object : ImageCapture.OnImageCapturedCallback() {
            override fun onCaptureSuccess(image: ImageProxy) {
                super.onCaptureSuccess(image)
                // image process

                // Turn on the torch again after capturing the photo
                openFlash()
            }

            override fun onError(exception: ImageCaptureException) {
                super.onError(exception)
                println("ERROR")
            }
        })
    }

我已经尝试过这个了。 - kallis
我已经试过了 - undefined

0
您应该在imageCapture构建器中使用setFlashMode(FLASH_MODE_ON)
imageCapture = ImageCapture.Builder()
        .setTargetRotation(rotation)
        .setFlashMode(FLASH_MODE_ON)
        .setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY)
        .build()

我已经尝试过这个了 - kallis
我已经试过了这个。 - undefined
我检查了一下,对我来说它是正常工作的。你能详细说明一下这个问题吗? - Upendra Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接