5

I faced with the issue of CameraX screen rotation support.

Portrait: see picture

Landscape: see picure

Transformation code:

private void updateTransform() {
    Log.d(TAG, "updateTransform: ");
    Matrix matrix = new Matrix();

    float centerX = cameraViewTextureV.getWidth() / 2f;
    float centerY = cameraViewTextureV.getHeight() / 2f;

    switch (cameraViewTextureV.getDisplay().getRotation()) {
        case Surface.ROTATION_0:
            rotation = 0;
            break;

        case Surface.ROTATION_90:
            rotation = 90;
            break;

        case Surface.ROTATION_180:
            rotation = 180;
            break;

        case Surface.ROTATION_270:
            rotation = 270;
            break;

        default:
            break;
    }

    matrix.postRotate((float) -rotation, centerX, centerY);

    cameraViewTextureV.setTransform(matrix);
}

So, as you can see in the pictures, camera support screen rotation not correctly... I calling updateTransform method when screen rotating... Took this code from the official guide for cameraX from Android developers site.

Will be very grateful for any proposes for fixing. Have a nice day!

Nikita Lapin
  • 149
  • 1
  • 1
  • 8

5 Answers5

4

Solution based on AutoFitPreviewBuilder:

preview.onPreviewOutputUpdateListener = Preview.OnPreviewOutputUpdateListener { output ->
    // Get all dimensions
    val metrics = DisplayMetrics().also { camera_texture_view.display.getRealMetrics(it) }
    val previewWidth = metrics.widthPixels
    val previewHeight = metrics.heightPixels
    val width = output.textureSize.width
    val height = output.textureSize.height
    val centerX = camera_texture_view.width.toFloat() / 2
    val centerY = camera_texture_view.height.toFloat() / 2

    // Get rotation
    val rotation = when (camera_texture_view.display.rotation) {
        Surface.ROTATION_0 -> 0
        Surface.ROTATION_90 -> 90
        Surface.ROTATION_180 -> 180
        Surface.ROTATION_270 -> 270
        else -> throw IllegalStateException()
    }
    val matrix = Matrix()
    // Rotate matrix
    matrix.postRotate(-rotation.toFloat(), centerX, centerY)
    // Scale matrix
    matrix.postScale(
        previewWidth.toFloat() / height,
        previewHeight.toFloat() / width,
        centerX,
        centerY
    )
    // Assign transformation to view
    camera_texture_view.setTransform(matrix)
    camera_texture_view.surfaceTexture = output.surfaceTexture
}
Marcin Mrugas
  • 973
  • 8
  • 17
  • It works for single side but if i am rotating device to otherside it is showing reverse image, Do you have any idea about it? – Nidhi Desai Dec 05 '19 at 14:16
  • this parameter we will not get in viewCamera.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { // updateTransform(); } }); – Nidhi Desai Dec 05 '19 at 14:17
1

Add this code

fun onCreate

viewFinder.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> updateTransform(1920,1080) }

fun startCamera

preview.setOnPreviewOutputUpdateListener {

        val parent = viewFinder.parent as ViewGroup
        parent.removeView(viewFinder)
        parent.addView(viewFinder, 0)

        viewFinder.surfaceTexture = it.surfaceTexture
        updateTransform(1920,1080)
    }

fun updateTransform(width:Int,height:Int)

        val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
    val previewWidth = metrics.widthPixels
    val previewHeight = metrics.heightPixels

    matrix.postScale(previewWidth.toFloat() / height,previewHeight.toFloat() /width,centerX,centerY)

The resolution of my device is 1920x1080

The complete code is in my repository CameraX

Ange1D
  • 43
  • 5
1

I had this issue with CameraX Alpha 06. I then solved it with Marcin Mrugas answer. But when migrating to Alpha09, I got rid of this code and the rotation was OK. So it seems CameraX now handles the rotation by itself.

Jérôme Pietri
  • 187
  • 1
  • 11
0

Try this transformation method from the official Android Camera X example project: https://github.com/android/camera-samples/blob/153d2d203118dacbd2afeb53b2e8be489677ed98/CameraXBasic/app/src/main/java/com/android/example/cameraxbasic/utils/AutoFitPreviewBuilder.kt#L151

I hope this helps.

Mike A
  • 707
  • 6
  • 9
0

From documentation

override fun onCreate() {
    val imageCapture = ImageCapture.Builder().build()

    val orientationEventListener = object : OrientationEventListener(this as Context) {
        override fun onOrientationChanged(orientation : Int) {
            // Monitors orientation values to determine the target rotation value
            val rotation : Int = when (orientation) {
                in 45..134 -> Surface.ROTATION_270
                in 135..224 -> Surface.ROTATION_180
                in 225..314 -> Surface.ROTATION_90
                else -> Surface.ROTATION_0
            }

            imageCapture.targetRotation = rotation
        }
    }
    orientationEventListener.enable()
}

Here is the link https://developer.android.com/training/camerax/configuration

Zoe
  • 27,060
  • 21
  • 118
  • 148
Shaon
  • 2,496
  • 26
  • 27