Home > Software design >  I have made a camera view app, I want the output of the image to be exactly as it is shown in the vi
I have made a camera view app, I want the output of the image to be exactly as it is shown in the vi

Time:09-02

You can see below the android view image differs from the output image, I want the output image exactly same as it is shown in the android view. I want to do this because in future I will add a box in the center and I can find the box position in the android view and I will use this position to cut out the image from the output image.

This is the code->

 @Composable
fun CameraView(
    isOpenFrontCamera: Boolean,
    outputDirectory: File,
    executor: Executor,
    onImageCaptured: (Uri) -> Unit,
    one rror: (ImageCaptureException) -> Unit,
    onCloseCameraClick: () -> Unit
) {
    val lensFacing: Int =
        if (isOpenFrontCamera) CameraSelector.LENS_FACING_FRONT else CameraSelector.LENS_FACING_BACK
    val context = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current

    val preview = Preview.Builder().build()
    val previewView = remember { PreviewView(context) }

    val imageCapture: ImageCapture = remember {
        ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY).build()
    }

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

    LaunchedEffect(lensFacing) {
        val cameraProvider = context.getCameraProvider()
        cameraProvider.unbindAll()
        cameraProvider.bindToLifecycle(
            lifecycleOwner,
            cameraSelector,
            preview,
            imageCapture
        )

        preview.setSurfaceProvider(previewView.surfaceProvider)
    }

    //Screen
    Box(
        contentAlignment = Alignment.BottomCenter,
        modifier = Modifier
            .fillMaxSize()) {
        AndroidView({ previewView }, modifier = Modifier.fillMaxSize())

        IconButton(
            modifier = Modifier.padding(bottom = 20.dp),
            onClick = {
                Log.d("takePhoto", "ON CLICK")
                takePhoto(
                    imageCapture = imageCapture,
                    outputDirectory = outputDirectory,
                    executor = executor,
                    onImageCaptured = { imageUri ->
                            onImageCaptured(imageUri)
                    },
                    one rror = one rror
                )
            },
            content = {
                Icon(
                    painter = painterResource(id = R.drawable.ic_baseline_camera_24),
                    contentDescription = stringResource(R.string.take_picture),
                    tint = Color.White,
                    modifier = Modifier
                        .fillMaxSize(0.2f)
                )
            }
        )
    }
}

  

Application ->

enter image description here

Output->

enter image description here

CodePudding user response:

I have made the logic like this, its working perfectly->

I can get the size of the screen by this->

  modifier = Modifier
            .fillMaxSize()
            .onGloballyPositioned { coordinates ->
                containerOverlaySize = coordinates.size
            }

The output image logic->

      takePhoto(
                imageCapture = imageCapture,
                outputDirectory = outputDirectory,
                executor = executor,
                onImageCaptured = { imageUri ->

                    val imageOriginal =
                        MediaStore.Images.Media.getBitmap(context.contentResolver, imageUri)

                    //The imageOriginal was rotated anti clockwise, so had to rotate it
                    val rotationMatrix = Matrix()
                    rotationMatrix.postRotate(90f)

                    val rotatedBitmap = Bitmap.createBitmap(
                        imageOriginal,
                        0,
                        0,
                        imageOriginal.width,
                        imageOriginal.height,
                        rotationMatrix,
                        false
                    )

                    val androidViewRatio:Float = containerOverlaySize.width.toFloat()/containerOverlaySize.height.toFloat()

                    val outputImageWidth = rotatedBitmap.height*androidViewRatio

                    val startingPositionToCut = rotatedBitmap.width/2 - outputImageWidth/2
                    
                    val outputBitmap = Bitmap.createBitmap(
                        rotatedBitmap,
                        startingPositionToCut.toInt(),
                        0,
                        (outputImageWidth).toInt(),
                        rotatedBitmap.height
                    )})

enter image description here

  • Related