How to crop image rectangle in camera preview on CameraX

I have a solution, I just use this function to cropping the Image after capturing the Image:

private fun cropImage(bitmap: Bitmap, frame: View, reference: View): ByteArray {
        val heightOriginal = frame.height
        val widthOriginal = frame.width
        val heightFrame = reference.height
        val widthFrame = reference.width
        val leftFrame = reference.left
        val topFrame = reference.top
        val heightReal = bitmap.height
        val widthReal = bitmap.width
        val widthFinal = widthFrame * widthReal / widthOriginal
        val heightFinal = heightFrame * heightReal / heightOriginal
        val leftFinal = leftFrame * widthReal / widthOriginal
        val topFinal = topFrame * heightReal / heightOriginal
        val bitmapFinal = Bitmap.createBitmap(
            bitmap,
            leftFinal, topFinal, widthFinal, heightFinal
        )
        val stream = ByteArrayOutputStream()
        bitmapFinal.compress(
            Bitmap.CompressFormat.JPEG,
            100,
            stream
        ) //100 is the best quality possibe
        return stream.toByteArray()
    }

Crop an image taking a reference a view parent like a frame and a view child like final reference

  • param bitmap image to crop
  • param frame where the image is set it
  • param reference frame to take reference for a crop the image
  • return image already cropped

You can see this example: https://github.com/rrifafauzikomara/CustomCamera/tree/custom_camerax


I found a simple and straight forward way of doing this using camerax configuration.

Get the height and width of your rectangle shape of the preview area that you need from the camera preview.

For example

<View
            android:background="@drawable/background_drawable"
            android:id="@+id/border_view"
            android:layout_gravity="center"
            android:layout_width="350dp"
            android:layout_height="100dp"/>

The width of mine is 350dp and a height of 100dp

Then use ViewPort to get the area you need

     val viewPort =  ViewPort.Builder(Rational(width, height), rotation).build()
//width = 350, height = 100, rotation = Surface.ROTATION_0 
    val useCaseGroup = UseCaseGroup.Builder()
        .addUseCase(preview) //your preview
        .addUseCase(imageAnalysis) //if you are using imageAnalysis
        .addUseCase(imageCapture)
        .setViewPort(viewPort)
        .build()

Then bind to LifeCycle of CameraProvider

cameraProvider.bindToLifecycle(this, cameraSelector, useCaseGroup)

Use this link CropRect for more information

If you need any help comment below, I can provide you with the working source code.

Edit

Link to Source Code Sample