2

Currently I have a problem with cropping a rectangle from the camera preview. Basically I have setup the camera using fotoapparat where I have setup the scaleType of the preview to be ScaleType.CenterCrop.

Because this stretches the preview to fill the screen (I have a full screen portrait mode camera preview) I don't know the true width of the camera. So now when I want to cut out rectangle from the image based on the size of the rectangle shown on screen it does not crop correctly in the width.

I had a simular issue in swift (iOS) but was able to solve it using metadataOutputRectConverted(fromLayerRect:)

I'd assume i'll have to do something like find out what the true size is the camera preview layer so including whatever is cropped off to fill the screen and based on that calculate the new width of the rectangle relative to the camera preview.

See my previous question regarding this but for swift. Just like in this post (see screenshots) the width is not cropping as expected.

Current cropping method, where the bitmap is the image we receive after taking a photo, the cameraView is basically just the width and height of the screen and the cropRectFrame is the rectangle in the screen which I want to crop anything inside of it.

    private fun cropImage(bitmap: Bitmap, cameraFrame: View, cropRectFrame: View): Bitmap {

        val heightOriginal = cameraFrame.height
        val widthOriginal = cameraFrame.width

        val heightFrame = cropRectFrame.height
        val widthFrame = cropRectFrame.width
        val leftFrame = cropRectFrame.left
        val topFrame = cropRectFrame.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)

        return Bitmap.createBitmap(
            bitmap, leftFinal, topFinal, widthFinal, heightFinal
        )
    }

any help is appreciated.

Robin
  • 704
  • 8
  • 24

1 Answers1

1

I figured it out with the following code.

private fun cropImage(bitmap: Bitmap, cameraFrame: View, cropRectFrame: View): Bitmap {
    val scaleFactor: Double; val widthOffset: Double; val heightOffset: Double

    if (cameraFrame.height * bitmap.width > cameraFrame.height * bitmap.width) {
        scaleFactor = (bitmap.width).toDouble() / (cameraFrame.width).toDouble()
        widthOffset = 0.0
        heightOffset = (bitmap.height - cameraFrame.height * scaleFactor) / 2
    } else {
        scaleFactor = (bitmap.height).toDouble() / (cameraFrame.height).toDouble()
        widthOffset = (bitmap.width - cameraFrame.width * scaleFactor) / 2
        heightOffset = 0.0
    }

    val newX = cropRectFrame.left * scaleFactor + widthOffset
    val newY = cropRectFrame.top * scaleFactor + heightOffset
    val width = cropRectFrame.width * scaleFactor
    val height = cropRectFrame.height * scaleFactor

    return Bitmap.createBitmap(bitmap, (newX).toInt(), (newY).toInt(), (width).toInt(), (height).toInt())

}
Robin
  • 704
  • 8
  • 24