@@ -6,9 +6,9 @@ import android.animation.ValueAnimator
6
6
import android.content.Intent
7
7
import android.graphics.BitmapFactory
8
8
import android.graphics.Matrix
9
+ // noinspection ExifInterface TODO Issue : #5994
9
10
import android.media.ExifInterface
10
11
import android.os.Bundle
11
- import android.util.Log
12
12
import android.view.animation.AccelerateDecelerateInterpolator
13
13
import android.widget.ImageView
14
14
import android.widget.Toast
@@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModelProvider
20
20
import fr.free.nrw.commons.databinding.ActivityEditBinding
21
21
import timber.log.Timber
22
22
import java.io.File
23
+ import kotlin.math.ceil
23
24
24
25
/* *
25
26
* An activity class for editing and rotating images using LLJTran with EXIF attribute preservation.
@@ -42,8 +43,11 @@ class EditActivity : AppCompatActivity() {
42
43
supportActionBar?.title = " "
43
44
val intent = intent
44
45
imageUri = intent.getStringExtra(" image" ) ? : " "
45
- vm = ViewModelProvider (this ).get( EditViewModel ::class .java)
46
+ vm = ViewModelProvider (this )[ EditViewModel ::class .java]
46
47
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" )
47
51
val exifTags =
48
52
arrayOf(
49
53
ExifInterface .TAG_APERTURE ,
@@ -88,38 +92,36 @@ class EditActivity : AppCompatActivity() {
88
92
private fun init () {
89
93
binding.iv.adjustViewBounds = true
90
94
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)
96
99
97
- val bitmapWidth = options.outWidth
98
- val bitmapHeight = options.outHeight
100
+ val bitmapWidth = options.outWidth
101
+ val bitmapHeight = options.outHeight
99
102
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)
116
119
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
+ }
123
125
binding.rotateBtn.setOnClickListener {
124
126
animateImageHeight()
125
127
}
@@ -143,15 +145,15 @@ class EditActivity : AppCompatActivity() {
143
145
val drawableWidth: Float =
144
146
binding.iv
145
147
.getDrawable()
146
- .getIntrinsicWidth()
148
+ .intrinsicWidth
147
149
.toFloat()
148
150
val drawableHeight: Float =
149
151
binding.iv
150
152
.getDrawable()
151
- .getIntrinsicHeight()
153
+ .intrinsicHeight
152
154
.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()
155
157
val rotation = imageRotation % 360
156
158
val newRotation = rotation + 90
157
159
@@ -162,16 +164,23 @@ class EditActivity : AppCompatActivity() {
162
164
Timber .d(" Rotation $rotation " )
163
165
Timber .d(" new Rotation $newRotation " )
164
166
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
+ }
175
184
}
176
185
177
186
val animator = ValueAnimator .ofFloat(0f , 1f ).setDuration(1000L )
@@ -204,7 +213,7 @@ class EditActivity : AppCompatActivity() {
204
213
(complementaryAnimVal * viewHeight + animVal * newViewHeight).toInt()
205
214
val animatedScale = complementaryAnimVal * imageScale + animVal * newImageScale
206
215
val animatedRotation = complementaryAnimVal * rotation + animVal * newRotation
207
- binding.iv.getLayoutParams() .height = animatedHeight
216
+ binding.iv.layoutParams .height = animatedHeight
208
217
val matrix: Matrix =
209
218
rotationMatrix(
210
219
animatedRotation,
@@ -218,8 +227,8 @@ class EditActivity : AppCompatActivity() {
218
227
drawableHeight / 2 ,
219
228
)
220
229
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 ,
223
232
)
224
233
binding.iv.setImageMatrix(matrix)
225
234
binding.iv.requestLayout()
@@ -267,9 +276,9 @@ class EditActivity : AppCompatActivity() {
267
276
*/
268
277
private fun copyExifData (editedImageExif : ExifInterface ? ) {
269
278
for (attr in sourceExifAttributeList) {
270
- Log .d(" Tag is ${attr.first} " , " Value is ${attr.second} " )
279
+ Timber .d(" Value is ${attr.second} " )
271
280
editedImageExif!! .setAttribute(attr.first, attr.second)
272
- Log .d(" Tag is ${attr.first} " , " Value is ${attr.second} " )
281
+ Timber .d(" Value is ${attr.second} " )
273
282
}
274
283
275
284
editedImageExif?.saveAttributes()
@@ -298,9 +307,10 @@ class EditActivity : AppCompatActivity() {
298
307
var scaleFactor = 1
299
308
300
309
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()
304
314
305
315
scaleFactor = if (widthRatio > heightRatio) widthRatio else heightRatio
306
316
}
0 commit comments