Hakshay
Hakshay

Reputation: 94

How to scale the camera preview to any given dimensions or shapes in a translucent background using Jetpack Compose

I have a dialog fragment with a translucent background. I want to place a camera preview on this dialog fragment either in the shape of a circle or a square.

On setting the scale type as PreviewView.ScaleType.FIT_CENTER, the preview is as follows:

camera preview with black borders

Whereas, if I were to set the scale type as PreviewView.ScaleType.FILL_CENTER, the preview is as follows:

camera preview overflowing out of set boundary

The following code is what I use for my Camera Preview Composable:

@Composable
private fun CameraPreview(
    modifier: Modifier = Modifier,
    scaleType: PreviewView.ScaleType = PreviewView.ScaleType.FILL_CENTER,
    onUseCase: (UseCase) -> Unit
) {
    AndroidView(
        modifier = modifier,
        factory = { context ->
            val previewView = PreviewView(context).apply {
                this.scaleType = scaleType
                layoutParams = ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT
                )
            }
            onUseCase(
                Preview.Builder()
                    .build()
                    .also {
                        it.setSurfaceProvider(previewView.surfaceProvider)
                    }
            )
            previewView
        }
    )
}

I have tried setting integral values for the layout parameters but that did not seem to help. How would I be able to set the camera preview such that it fits the bounds and does not extend beyond it or leaves a black border around it?

Here is an image for reference which shows what I would like to achieve:

image of what I'd like to achieve

Upvotes: 6

Views: 2036

Answers (1)

Dhanesh Katre
Dhanesh Katre

Reputation: 291

I was facing same problem for my QR code scanning implementation. Adding a box to AndroidView as a parent, and adding Modifier.clipToBounds() to it helped achieving the correct results.

Snippet:

Box(
    modifier = Modifier
        .fillMaxWidth()
        .height(240.dp)
        .clipToBounds()
) {
    CameraPreviewWithQRScanning(
        modifier = Modifier
            .matchParentSize()
            .align(Alignment.Center),
        isFlashOn = state.isFlashOn,
        onQrCodeScanned = viewModel::onQrCodeScanned
    )
}

CameraPreviewWithQRScanning is a Composable function with AndroidView in it. Try adding such a box with your required size once and see if it helps..

Upvotes: 16

Related Questions