Skip to content

Commit f2e7c76

Browse files
Fixed bitmap too large issue (commons-app#5430)
1 parent b7090d9 commit f2e7c76

File tree

1 file changed

+58
-7
lines changed

1 file changed

+58
-7
lines changed

app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,33 @@ class EditActivity : AppCompatActivity() {
9090
iv.adjustViewBounds = true
9191
iv.scaleType = ImageView.ScaleType.MATRIX
9292
iv.post(Runnable {
93-
val bitmap = BitmapFactory.decodeFile(imageUri)
94-
iv.setImageBitmap(bitmap)
95-
if (bitmap.width > 0) {
96-
val scale =
97-
iv.measuredWidth.toFloat() / (iv.drawable as BitmapDrawable).bitmap.width.toFloat()
98-
iv.layoutParams.height =
99-
(scale * (iv.drawable as BitmapDrawable).bitmap.height).toInt()
93+
val options = BitmapFactory.Options()
94+
options.inJustDecodeBounds = true
95+
BitmapFactory.decodeFile(imageUri, options)
96+
97+
val bitmapWidth = options.outWidth
98+
val bitmapHeight = options.outHeight
99+
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+
iv.setImageBitmap(scaledBitmap)
108+
// Update the ImageView with the scaled bitmap
109+
val scale = iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat()
110+
iv.layoutParams.height = (scale * scaledBitmap.height).toInt()
111+
iv.imageMatrix = scaleMatrix(scale, scale)
112+
} else {
113+
114+
options.inJustDecodeBounds = false
115+
val bitmap = BitmapFactory.decodeFile(imageUri, options)
116+
iv.setImageBitmap(bitmap)
117+
118+
val scale = iv.measuredWidth.toFloat() / bitmapWidth.toFloat()
119+
iv.layoutParams.height = (scale * bitmapHeight).toInt()
100120
iv.imageMatrix = scaleMatrix(scale, scale)
101121
}
102122
})
@@ -246,4 +266,35 @@ class EditActivity : AppCompatActivity() {
246266
editedImageExif?.saveAttributes()
247267
}
248268

269+
/**
270+
* Calculates the scale factor to be used for scaling down a bitmap based on its original
271+
* dimensions and the maximum allowed size.
272+
* @param originalWidth The original width of the bitmap.
273+
* @param originalHeight The original height of the bitmap.
274+
* @param maxSize The maximum allowed size for either width or height.
275+
* @return The scale factor to be used for scaling down the bitmap.
276+
* If the bitmap is smaller than or equal to the maximum size in both dimensions,
277+
* the scale factor is 1.
278+
* If the bitmap is larger than the maximum size in either dimension,
279+
* the scale factor is calculated as the largest power of 2 that is less than or equal
280+
* to the ratio of the original dimension to the maximum size.
281+
* The scale factor ensures that the scaled bitmap will fit within the maximum size
282+
* while maintaining aspect ratio.
283+
*/
284+
private fun calculateScaleFactor(originalWidth: Int, originalHeight: Int, maxSize: Int): Int {
285+
var scaleFactor = 1
286+
287+
if (originalWidth > maxSize || originalHeight > maxSize) {
288+
// Calculate the largest power of 2 that is less than or equal to the desired width and height
289+
val widthRatio = Math.ceil((originalWidth.toDouble() / maxSize.toDouble())).toInt()
290+
val heightRatio = Math.ceil((originalHeight.toDouble() / maxSize.toDouble())).toInt()
291+
292+
scaleFactor = if (widthRatio > heightRatio) widthRatio else heightRatio
293+
}
294+
295+
return scaleFactor
296+
}
297+
298+
299+
249300
}

0 commit comments

Comments
 (0)