CameraX doesn't show preview when I use useCaseGroupBuilder with ViewPort, but is able to capture

84 Views Asked by At

The reason I want to use useCaseGroupBuilder is I need same FOV or ratio in preview and captured image. I saw that I should use viewPort and I did My startCamera function:

private suspend fun startCamera() {
        val cameraProvider = ProcessCameraProvider.getInstance(this).await()

        val preview = androidx.camera.core.Preview.Builder()
            .build().also {
                it.setSurfaceProvider(mPreviewView.surfaceProvider)
            }

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

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

        try {
            cameraProvider.unbindAll()

            val viewPort: ViewPort =
                ViewPort.Builder(
                    Rational(
                        mPreviewView.width,
                        mPreviewView.height
                    ),
                    mPreviewView.display.rotation
                ).setScaleType(ViewPort.FILL_CENTER).build()

            val useCaseGroupBuilder: UseCaseGroup.Builder = UseCaseGroup.Builder()
                .addUseCase(imageCapture ?: return)
                .addUseCase(preview)
                .setViewPort(
                    viewPort
                )

            val camera = cameraProvider.bindToLifecycle(
                this, cameraSelector,
                useCaseGroupBuilder.build()
            )

            mFlash.setBackgroundResource(
                if (imageCapture?.flashMode == FLASH_MODE_OFF) {
                    R.drawable.sm_flash_off
                } else {
                    R.drawable.sm_flash_on
                }
            )

            mFlash.setOnClickListener {
                if (camera.cameraInfo.hasFlashUnit()) {
                    onFlashClick(imageCapture)
                } else {
                    runOnUiThread {
                        Toast.makeText(this, "Flash is not available currently", Toast.LENGTH_LONG)
                            .show()
                    }
                }
            }

            mButton.setOnClickListener {
                takePhoto()
            }

        } catch (e: Exception) {
            Log.e(logTag, "UseCase binding failed", e)
        }
    }

My XML(only required part). preview actually works when I change layout_width and layout_height to match_parent, but the captured image has different ratio or size

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SmartMerchCameraActivity"
    tools:visibility="visible">

    <androidx.camera.view.PreviewView
        android:id="@+id/preview_view"
        android:layout_alignParentEnd="true"
        android:layout_alignParentStart="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

I tried this code, it works but it's not WYSIWYG, the preview differs from captured image.

val camera = cameraProvider.bindToLifecycle(
                this, cameraSelector,
                preview, imageCapture
)
0

There are 0 best solutions below