Fix image viewer rotation handling

This commit is contained in:
Matéo Duparc 2022-04-16 16:42:47 +02:00
parent e6a1285e0a
commit 339309b00d
Signed by untrusted user: hardcoresushi
GPG Key ID: AFE384344A45E13A

View File

@ -11,6 +11,7 @@ import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.exifinterface.media.ExifInterface
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
@ -39,8 +40,9 @@ class ImageViewer: FileViewerActivity() {
private var x1 = 0F private var x1 = 0F
private var x2 = 0F private var x2 = 0F
private var slideshowActive = false private var slideshowActive = false
private var originalOrientation: Float = 0f
private var rotationAngle: Float = 0F private var rotationAngle: Float = 0F
private var rotatedBitmap: Bitmap? = null private var orientationTransformation: OrientationTransformation? = null
private val hideUI = Runnable { private val hideUI = Runnable {
binding.actionButtons.visibility = View.GONE binding.actionButtons.visibility = View.GONE
binding.topBar.visibility = View.GONE binding.topBar.visibility = View.GONE
@ -164,6 +166,16 @@ class ImageViewer: FileViewerActivity() {
if (bitmap == null) { if (bitmap == null) {
true true
} else { } else {
val orientation = ExifInterface(ByteArrayInputStream(it)).getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL
)
originalOrientation = when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> 90f
ExifInterface.ORIENTATION_ROTATE_180 -> 180f
ExifInterface.ORIENTATION_ROTATE_270 -> 270f
else -> 0f
}
val displayMetrics = Resources.getSystem().displayMetrics val displayMetrics = Resources.getSystem().displayMetrics
if (displayMetrics.widthPixels < bitmap!!.width || displayMetrics.heightPixels < bitmap!!.height) { if (displayMetrics.widthPixels < bitmap!!.width || displayMetrics.heightPixels < bitmap!!.height) {
val newWidth: Int val newWidth: Int
@ -177,17 +189,18 @@ class ImageViewer: FileViewerActivity() {
} }
bitmap = Bitmap.createScaledBitmap(bitmap!!, newWidth, newHeight, false) bitmap = Bitmap.createScaledBitmap(bitmap!!, newWidth, newHeight, false)
} }
Glide.with(this).load(bitmap).into(binding.imageViewer) Glide.with(this).load(bitmap).transform(OrientationTransformation(originalOrientation)).into(binding.imageViewer)
false false
} }
} }
if (displayWithGlide) { if (displayWithGlide) {
originalOrientation = 0f
requestBuilder = Glide.with(this).load(it) requestBuilder = Glide.with(this).load(it)
requestBuilder?.into(binding.imageViewer) requestBuilder?.into(binding.imageViewer)
} }
fileName = File(filePath).name fileName = File(filePath).name
binding.textFilename.text = fileName binding.textFilename.text = fileName
rotationAngle = 0F rotationAngle = originalOrientation
} }
} }
@ -222,28 +235,31 @@ class ImageViewer: FileViewerActivity() {
} }
} }
class RotateTransformation(private val imageViewer: ImageViewer): BitmapTransformation() { class OrientationTransformation(private val orientation: Float): BitmapTransformation() {
lateinit var bitmap: Bitmap
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? { override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? {
val matrix = Matrix() return Bitmap.createBitmap(toTransform, 0, 0, toTransform.width, toTransform.height, Matrix().apply {
matrix.postRotate(imageViewer.rotationAngle) postRotate(orientation)
imageViewer.rotatedBitmap = Bitmap.createBitmap(toTransform, 0, 0, toTransform.width, toTransform.height, matrix, true) }, true).also {
return imageViewer.rotatedBitmap bitmap = it
}
} }
override fun updateDiskCacheKey(messageDigest: MessageDigest) { override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update("rotate${imageViewer.rotationAngle}".toByteArray()) messageDigest.update("rotate$orientation".toByteArray())
} }
} }
private fun rotateImage(){ private fun rotateImage(){
binding.imageViewer.restoreZoomNormal() binding.imageViewer.restoreZoomNormal()
(requestBuilder ?: Glide.with(this).load(bitmap)) orientationTransformation = OrientationTransformation(rotationAngle)
.transform(RotateTransformation(this)).into(binding.imageViewer) (requestBuilder ?: Glide.with(this).load(bitmap)).transform(orientationTransformation).into(binding.imageViewer)
} }
private fun askSaveRotation(callback: () -> Unit){ private fun askSaveRotation(callback: () -> Unit){
if (rotationAngle%360 != 0f && !slideshowActive){ if (rotationAngle.mod(360f) != originalOrientation && !slideshowActive) {
CustomAlertDialogBuilder(this, themeValue) CustomAlertDialogBuilder(this, themeValue)
.keepFullScreen() .keepFullScreen()
.setTitle(R.string.warning) .setTitle(R.string.warning)
@ -252,7 +268,7 @@ class ImageViewer: FileViewerActivity() {
.setNeutralButton(R.string.cancel, null) .setNeutralButton(R.string.cancel, null)
.setPositiveButton(R.string.yes) { _, _ -> .setPositiveButton(R.string.yes) { _, _ ->
val outputStream = ByteArrayOutputStream() val outputStream = ByteArrayOutputStream()
if (rotatedBitmap?.compress( if (orientationTransformation?.bitmap?.compress(
if (fileName.endsWith("png", true)){ if (fileName.endsWith("png", true)){
Bitmap.CompressFormat.PNG Bitmap.CompressFormat.PNG
} else { } else {