如何在 CameraX 上切换到前置摄像头?

And*_*ble 5 android android-camerax

我已按照此处的步骤进行 CameraX 设置,现在我正在尝试使前置摄像头按钮正常工作。

这是我的设置代码:

private lateinit var preview: Preview

private fun startCamera() {

    // Create configuration object for the viewfinder use case
    val previewConfig = PreviewConfig.Builder().apply {
        setLensFacing(CameraX.LensFacing.BACK)
    }.build()

    // Build the viewfinder use case
    preview = Preview(previewConfig)

    // Every time the viewfinder is updated, recompute layout
    preview.setOnPreviewOutputUpdateListener {

        // To update the SurfaceTexture, we have to remove it and re-add it
        val parent = viewFinder.parent as ViewGroup
        parent.removeView(viewFinder)
        parent.addView(viewFinder, 0)

        viewFinder.surfaceTexture = it.surfaceTexture
        updateTransform()
    }

    // Bind use cases to lifecycle
    CameraX.bindToLifecycle(this, preview)
}
Run Code Online (Sandbox Code Playgroud)

当用户单击“切换”按钮时,我重新配置预览以使用前置摄像头,然后重新初始化预览。

private fun initSwitchButton(view: View) {
    switchButton = view.findViewById(R.id.switch_button)
    switchButton.setOnClickListener {
        val previewConfig = PreviewConfig.Builder().apply { setLensFacing(CameraX.LensFacing.FRONT) }.build()
        preview = Preview(previewConfig)
    }
}

Run Code Online (Sandbox Code Playgroud)

但是,这不会切换到前置摄像头。我错过了什么?

小智 21

自 2021 年以来,CameraX 的更新已变得CameraX.LensFacing无法使用。CameraSelector代替使用。

    private CameraSelector lensFacing = CameraSelector.DEFAULT_FRONT_CAMERA;

    private void flipCamera() {
        if (lensFacing == CameraSelector.DEFAULT_FRONT_CAMERA) lensFacing = CameraSelector.DEFAULT_BACK_CAMERA;
        else if (lensFacing == CameraSelector.DEFAULT_BACK_CAMERA) lensFacing = CameraSelector.DEFAULT_FRONT_CAMERA;
        startCamera();
    }

    private void startCamera() {
        ListenableFuture<ProcessCameraProvider> cameraFuture = ProcessCameraProvider.getInstance(requireContext());

        cameraFuture.addListener(() -> {
            imageCapture = new ImageCapture.Builder()
                .setTargetRotation(cameraPreview.getDisplay().getRotation())
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build();
            videoCapture = new VideoCapture.Builder().build();

        try {
            ProcessCameraProvider processCameraProvider = cameraFuture.get();
            Preview preview = new Preview.Builder().build();
            preview.setSurfaceProvider(cameraPreview.getSurfaceProvider());
            processCameraProvider.unbindAll(); 

            // lensFacing is used here
            processCameraProvider.bindToLifecycle(getViewLifecycleOwner(), lensFacing, imageCapture, videoCapture, preview);
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }, ContextCompat.getMainExecutor(requireContext()));
    }
Run Code Online (Sandbox Code Playgroud)


And*_*ble 8

看起来实现这一点的推荐方法是将LensFacing位置存储为实例变量,然后调用bindToLifecycle()以切换相机。

这是一个对我有用的代码片段:

private var lensFacing = CameraX.LensFacing.BACK
private var imageCapture: ImageCapture? = null

@SuppressLint("RestrictedApi")
private fun startCamera() {
    bindCameraUseCases()

    // Listener for button used to switch cameras
    switchButton = view.findViewById(R.id.switch_button)
    switchButton.setOnClickListener {
        lensFacing = if (CameraX.LensFacing.FRONT == lensFacing) {
            CameraX.LensFacing.BACK
        } else {
            CameraX.LensFacing.FRONT
        }
        try {
            // Only bind use cases if we can query a camera with this orientation
            CameraX.getCameraWithLensFacing(lensFacing)
            bindCameraUseCases()
        } catch (exc: Exception) {
            // Do nothing
        }
    }
}

private fun bindCameraUseCases() {
    // Make sure that there are no other use cases bound to CameraX
    CameraX.unbindAll()

    val previewConfig = PreviewConfig.Builder().apply {
        setLensFacing(lensFacing)
    }.build()
    val preview = Preview(previewConfig)

    val imageCaptureConfig = ImageCaptureConfig.Builder().apply {
        setLensFacing(lensFacing)
    }.build()
    imageCapture = ImageCapture(imageCaptureConfig)

    // Apply declared configs to CameraX using the same lifecycle owner
    CameraX.bindToLifecycle(this, preview, imageCapture)
}
Run Code Online (Sandbox Code Playgroud)

  • 没有“CameraX.LensFacing.BACK”常量。它应该是“CameraSelector.LENS_FACING_BACK” (3认同)