Image rotation issue
koolfreak opened this issue · comments
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. 😄
@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)
}