ujizin / Camposer

Camera Library for Android Jetpack Compose. 📸✨

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Image rotation issue

koolfreak opened this issue · comments

commented

please complete the following information

  • Device: Samsung S8
  • Android version: Android 8
  • Library version: 0.1.0

Describe the bug

A clear and concise description of what the bug is.

To Reproduce
Capture image in portrait mode
Normal configuration and setup of camerax - here is the link of the video of the issue

https://drive.google.com/file/d/1MfzUONmr0ggrY2_bVAWNZEO6Q1GRZ7lQ/view?usp=share_link

Expected behavior

Since I captured it on portrait mode the image preview should be on portrait also

Screenshots

If applicable, add screenshots to help explain your problem.

https://drive.google.com/file/d/1MfzUONmr0ggrY2_bVAWNZEO6Q1GRZ7lQ/view?usp=share_link

Really dont know if it is a bug or not? is it camerax bug or not?
Any idea why this happening?

Thanks a lot!

Hey @koolfreak, thanks for reporting the issue!

After investigating the issue, it appears that the correct orientation of the image needs to be recovered by EXIF. You can check in the docs

In my side project, I used this ByteArray extension. It may be useful for you as well:

fun ByteArray.decodeToBitmapWithRotation(): Bitmap? {
    val bitmap = BitmapFactory.decodeByteArray(this, 0, size) ?: return null

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return bitmap

    val orientation = ExifInterface(ByteArrayInputStream(this)).getAttributeInt(
        ExifInterface.TAG_ORIENTATION,
        ExifInterface.ORIENTATION_UNDEFINED,
    )

    val degrees = when (orientation) {
        ExifInterface.ORIENTATION_ROTATE_90 -> 90F
        ExifInterface.ORIENTATION_ROTATE_180 -> 180F
        ExifInterface.ORIENTATION_ROTATE_270 -> 270F
        else -> 0F
    }

    val matrix = Matrix().apply { postRotate(degrees) }

    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}

If this solution doesn't fix the issue, please don't hesitate to let me know so that I can provide further assistance. 😄

commented

@ujizin it works on my side too. thanks for this sharing this solution! awesome!

@ujizin doesn't work for me. It says that orientation is ORIENTATION_TRANSVERSE so I guess we need to add some more when conditions

val degrees = when (orientation) {
        ExifInterface.ORIENTATION_ROTATE_90 -> 90F
        ExifInterface.ORIENTATION_TRANSPOSE -> 90F
        ExifInterface.ORIENTATION_ROTATE_180 -> 180F
        ExifInterface.ORIENTATION_ROTATE_270 -> -90F
        ExifInterface.ORIENTATION_TRANSVERSE -> -90F
        else -> 0F
    }

smth like this

Hey @lectricas, there was missing some orientation... I upgraded it, and now I've reached this code:

fun ByteArray.decodeToBitmapWithRotation(): Bitmap? {
    val bitmap = BitmapFactory.decodeByteArray(this, 0, size) ?: return null

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return bitmap

    val orientation = ExifInterface(ByteArrayInputStream(this)).getAttributeInt(
        ExifInterface.TAG_ORIENTATION,
        ExifInterface.ORIENTATION_UNDEFINED,
    )

    val degrees = when (orientation) {
        ExifInterface.ORIENTATION_ROTATE_90, ExifInterface.ORIENTATION_TRANSPOSE -> 90F
        ExifInterface.ORIENTATION_ROTATE_180, ExifInterface.ORIENTATION_FLIP_VERTICAL -> 180F
        ExifInterface.ORIENTATION_ROTATE_270 -> 270F
        ExifInterface.ORIENTATION_TRANSVERSE -> -90F
        else -> 0F
    }

    val scale = when (orientation) {
        ExifInterface.ORIENTATION_FLIP_HORIZONTAL,
        ExifInterface.ORIENTATION_FLIP_VERTICAL,
        ExifInterface.ORIENTATION_TRANSPOSE,
        ExifInterface.ORIENTATION_TRANSVERSE -> -1F to 1F
        else -> 1F to 1F
    }

    val matrix = Matrix().apply {
        postRotate(degrees)
        postScale(scale.first, scale.second)
    }

    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}