@@ -6,9 +6,9 @@ import android.animation.ValueAnimator
66import android.content.Intent
77import android.graphics.BitmapFactory
88import android.graphics.Matrix
9+ // noinspection ExifInterface TODO Issue : #5994
910import android.media.ExifInterface
1011import android.os.Bundle
11- import android.util.Log
1212import android.view.animation.AccelerateDecelerateInterpolator
1313import android.widget.ImageView
1414import android.widget.Toast
@@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModelProvider
2020import fr.free.nrw.commons.databinding.ActivityEditBinding
2121import timber.log.Timber
2222import java.io.File
23+ import kotlin.math.ceil
2324
2425/* *
2526 * An activity class for editing and rotating images using LLJTran with EXIF attribute preservation.
@@ -42,8 +43,11 @@ class EditActivity : AppCompatActivity() {
4243 supportActionBar?.title = " "
4344 val intent = intent
4445 imageUri = intent.getStringExtra(" image" ) ? : " "
45- vm = ViewModelProvider (this ).get( EditViewModel ::class .java)
46+ vm = ViewModelProvider (this )[ EditViewModel ::class .java]
4647 val sourceExif = imageUri.toUri().path?.let { ExifInterface (it) }
48+ // TODO(Deprecation : 'TAG_APERTURE: String' is deprecated. Deprecated in Java) Issue : #6001
49+ // TODO(Deprecation : 'TAG_ISO: String' is deprecated. Deprecated in Java) Issue : #6001
50+ @Suppress(" DEPRECATION" )
4751 val exifTags =
4852 arrayOf(
4953 ExifInterface .TAG_APERTURE ,
@@ -88,38 +92,36 @@ class EditActivity : AppCompatActivity() {
8892 private fun init () {
8993 binding.iv.adjustViewBounds = true
9094 binding.iv.scaleType = ImageView .ScaleType .MATRIX
91- binding.iv.post(
92- Runnable {
93- val options = BitmapFactory .Options ()
94- options.inJustDecodeBounds = true
95- BitmapFactory .decodeFile(imageUri, options)
95+ binding.iv.post {
96+ val options = BitmapFactory .Options ()
97+ options.inJustDecodeBounds = true
98+ BitmapFactory .decodeFile(imageUri, options)
9699
97- val bitmapWidth = options.outWidth
98- val bitmapHeight = options.outHeight
100+ val bitmapWidth = options.outWidth
101+ val bitmapHeight = options.outHeight
99102
100- // Check if the bitmap dimensions exceed a certain threshold
101- val maxBitmapSize = 2000 // Set your maximum size here
102- if (bitmapWidth > maxBitmapSize || bitmapHeight > maxBitmapSize) {
103- val scaleFactor = calculateScaleFactor(bitmapWidth, bitmapHeight, maxBitmapSize)
104- options.inSampleSize = scaleFactor
105- options.inJustDecodeBounds = false
106- val scaledBitmap = BitmapFactory .decodeFile(imageUri, options)
107- binding.iv.setImageBitmap(scaledBitmap)
108- // Update the ImageView with the scaled bitmap
109- val scale = binding.iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat()
110- binding.iv.layoutParams.height = (scale * scaledBitmap.height).toInt()
111- binding.iv.imageMatrix = scaleMatrix(scale, scale)
112- } else {
113- options.inJustDecodeBounds = false
114- val bitmap = BitmapFactory .decodeFile(imageUri, options)
115- binding.iv.setImageBitmap(bitmap)
103+ // Check if the bitmap dimensions exceed a certain threshold
104+ val maxBitmapSize = 2000 // Set your maximum size here
105+ if (bitmapWidth > maxBitmapSize || bitmapHeight > maxBitmapSize) {
106+ val scaleFactor = calculateScaleFactor(bitmapWidth, bitmapHeight, maxBitmapSize)
107+ options.inSampleSize = scaleFactor
108+ options.inJustDecodeBounds = false
109+ val scaledBitmap = BitmapFactory .decodeFile(imageUri, options)
110+ binding.iv.setImageBitmap(scaledBitmap)
111+ // Update the ImageView with the scaled bitmap
112+ val scale = binding.iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat()
113+ binding.iv.layoutParams.height = (scale * scaledBitmap.height).toInt()
114+ binding.iv.imageMatrix = scaleMatrix(scale, scale)
115+ } else {
116+ options.inJustDecodeBounds = false
117+ val bitmap = BitmapFactory .decodeFile(imageUri, options)
118+ binding.iv.setImageBitmap(bitmap)
116119
117- val scale = binding.iv.measuredWidth.toFloat() / bitmapWidth.toFloat()
118- binding.iv.layoutParams.height = (scale * bitmapHeight).toInt()
119- binding.iv.imageMatrix = scaleMatrix(scale, scale)
120- }
121- },
122- )
120+ val scale = binding.iv.measuredWidth.toFloat() / bitmapWidth.toFloat()
121+ binding.iv.layoutParams.height = (scale * bitmapHeight).toInt()
122+ binding.iv.imageMatrix = scaleMatrix(scale, scale)
123+ }
124+ }
123125 binding.rotateBtn.setOnClickListener {
124126 animateImageHeight()
125127 }
@@ -143,15 +145,15 @@ class EditActivity : AppCompatActivity() {
143145 val drawableWidth: Float =
144146 binding.iv
145147 .getDrawable()
146- .getIntrinsicWidth()
148+ .intrinsicWidth
147149 .toFloat()
148150 val drawableHeight: Float =
149151 binding.iv
150152 .getDrawable()
151- .getIntrinsicHeight()
153+ .intrinsicHeight
152154 .toFloat()
153- val viewWidth: Float = binding.iv.getMeasuredWidth() .toFloat()
154- val viewHeight: Float = binding.iv.getMeasuredHeight() .toFloat()
155+ val viewWidth: Float = binding.iv.measuredWidth .toFloat()
156+ val viewHeight: Float = binding.iv.measuredHeight .toFloat()
155157 val rotation = imageRotation % 360
156158 val newRotation = rotation + 90
157159
@@ -162,16 +164,23 @@ class EditActivity : AppCompatActivity() {
162164 Timber .d(" Rotation $rotation " )
163165 Timber .d(" new Rotation $newRotation " )
164166
165- if (rotation == 0 || rotation == 180 ) {
166- imageScale = viewWidth / drawableWidth
167- newImageScale = viewWidth / drawableHeight
168- newViewHeight = (drawableWidth * newImageScale).toInt()
169- } else if (rotation == 90 || rotation == 270 ) {
170- imageScale = viewWidth / drawableHeight
171- newImageScale = viewWidth / drawableWidth
172- newViewHeight = (drawableHeight * newImageScale).toInt()
173- } else {
174- throw UnsupportedOperationException (" rotation can 0, 90, 180 or 270. \$ {rotation} is unsupported" )
167+ when (rotation) {
168+ 0 , 180 -> {
169+ imageScale = viewWidth / drawableWidth
170+ newImageScale = viewWidth / drawableHeight
171+ newViewHeight = (drawableWidth * newImageScale).toInt()
172+ }
173+ 90 , 270 -> {
174+ imageScale = viewWidth / drawableHeight
175+ newImageScale = viewWidth / drawableWidth
176+ newViewHeight = (drawableHeight * newImageScale).toInt()
177+ }
178+ else -> {
179+ throw
180+ UnsupportedOperationException (
181+ " rotation can 0, 90, 180 or 270. \$ {rotation} is unsupported"
182+ )
183+ }
175184 }
176185
177186 val animator = ValueAnimator .ofFloat(0f , 1f ).setDuration(1000L )
@@ -204,7 +213,7 @@ class EditActivity : AppCompatActivity() {
204213 (complementaryAnimVal * viewHeight + animVal * newViewHeight).toInt()
205214 val animatedScale = complementaryAnimVal * imageScale + animVal * newImageScale
206215 val animatedRotation = complementaryAnimVal * rotation + animVal * newRotation
207- binding.iv.getLayoutParams() .height = animatedHeight
216+ binding.iv.layoutParams .height = animatedHeight
208217 val matrix: Matrix =
209218 rotationMatrix(
210219 animatedRotation,
@@ -218,8 +227,8 @@ class EditActivity : AppCompatActivity() {
218227 drawableHeight / 2 ,
219228 )
220229 matrix.postTranslate(
221- - (drawableWidth - binding.iv.getMeasuredWidth() ) / 2 ,
222- - (drawableHeight - binding.iv.getMeasuredHeight() ) / 2 ,
230+ - (drawableWidth - binding.iv.measuredWidth ) / 2 ,
231+ - (drawableHeight - binding.iv.measuredHeight ) / 2 ,
223232 )
224233 binding.iv.setImageMatrix(matrix)
225234 binding.iv.requestLayout()
@@ -267,9 +276,9 @@ class EditActivity : AppCompatActivity() {
267276 */
268277 private fun copyExifData (editedImageExif : ExifInterface ? ) {
269278 for (attr in sourceExifAttributeList) {
270- Log .d(" Tag is ${attr.first} " , " Value is ${attr.second} " )
279+ Timber .d(" Value is ${attr.second} " )
271280 editedImageExif!! .setAttribute(attr.first, attr.second)
272- Log .d(" Tag is ${attr.first} " , " Value is ${attr.second} " )
281+ Timber .d(" Value is ${attr.second} " )
273282 }
274283
275284 editedImageExif?.saveAttributes()
@@ -298,9 +307,10 @@ class EditActivity : AppCompatActivity() {
298307 var scaleFactor = 1
299308
300309 if (originalWidth > maxSize || originalHeight > maxSize) {
301- // Calculate the largest power of 2 that is less than or equal to the desired width and height
302- val widthRatio = Math .ceil((originalWidth.toDouble() / maxSize.toDouble())).toInt()
303- val heightRatio = Math .ceil((originalHeight.toDouble() / maxSize.toDouble())).toInt()
310+ // Calculate the largest power of 2 that is less than or equal to the desired
311+ // width and height
312+ val widthRatio = ceil((originalWidth.toDouble() / maxSize.toDouble())).toInt()
313+ val heightRatio = ceil((originalHeight.toDouble() / maxSize.toDouble())).toInt()
304314
305315 scaleFactor = if (widthRatio > heightRatio) widthRatio else heightRatio
306316 }
0 commit comments