Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Selected image get rotate in edit profile
- Loading branch information
1 parent
ff9ce2e
commit 43f691e
Showing
4 changed files
with
175 additions
and
32 deletions.
There are no files selected for viewing
114 changes: 114 additions & 0 deletions
114
app/src/main/java/org/fossasia/openevent/general/RotateBitmap.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package org.fossasia.openevent.general | ||
|
||
import android.content.Context | ||
import android.graphics.Bitmap | ||
import android.graphics.BitmapFactory | ||
import android.graphics.Matrix | ||
import android.net.Uri | ||
import androidx.exifinterface.media.ExifInterface | ||
import java.io.IOException | ||
|
||
/** | ||
* Handle the image rotation | ||
*/ | ||
|
||
class RotateBitmap { | ||
|
||
private var context: Context? = null | ||
|
||
/** | ||
* This method is responsible for solving the rotation issue if exist. Also scale the images to | ||
* 1024x1024 resolution | ||
* | ||
* @param selectedImage The Image URI | ||
* @return Bitmap image results | ||
* @throws IOException | ||
*/ | ||
@Throws(IOException::class) | ||
fun handleSamplingAndRotationBitmap(context: Context, selectedImage: Uri): Bitmap? { | ||
this.context = context | ||
val MAX_HEIGHT = 1024 | ||
val MAX_WIDTH = 1024 | ||
|
||
// First decode with inJustDecodeBounds=true to check dimensions | ||
val options = BitmapFactory.Options() | ||
options.inJustDecodeBounds = true | ||
var imageStream = context.contentResolver.openInputStream(selectedImage) | ||
BitmapFactory.decodeStream(imageStream, null, options) | ||
imageStream?.close() | ||
|
||
// Calculate inSampleSize | ||
options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT) | ||
|
||
// Decode bitmap with inSampleSize set | ||
options.inJustDecodeBounds = false | ||
imageStream = context.contentResolver.openInputStream(selectedImage) | ||
var img = BitmapFactory.decodeStream(imageStream, null, options) | ||
|
||
img = rotateImageIfRequired(img, selectedImage) | ||
return img | ||
} | ||
|
||
@Throws(IOException::class) | ||
private fun rotateImageIfRequired(img: Bitmap?, selectedImage: Uri): Bitmap? { | ||
|
||
val input = context?.contentResolver?.openInputStream(selectedImage) | ||
val ei = input?.let { ExifInterface(it) } | ||
val orientation = ei?.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) | ||
return when (orientation) { | ||
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(img, 90) | ||
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(img, 180) | ||
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(img, 270) | ||
else -> img | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
private fun rotateImage(img: Bitmap?, degree: Int): Bitmap? { | ||
val matrix = Matrix() | ||
matrix.postRotate(degree.toFloat()) | ||
val rotatedImg = img?.let { Bitmap.createBitmap(it, 0, 0, img.width, img.height, matrix, true) } | ||
img?.recycle() | ||
return rotatedImg | ||
} | ||
|
||
private fun calculateInSampleSize( | ||
options: BitmapFactory.Options, | ||
reqWidth: Int, | ||
reqHeight: Int | ||
): Int { | ||
// Raw height and width of image | ||
val height = options.outHeight | ||
val width = options.outWidth | ||
var inSampleSize = 1 | ||
|
||
if (height > reqHeight || width > reqWidth) { | ||
|
||
// Calculate ratios of height and width to requested height and width | ||
val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat()) | ||
val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat()) | ||
|
||
// Choose the smallest ratio as inSampleSize value, this will guarantee a final image | ||
// with both dimensions larger than or equal to the requested height and width. | ||
inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio | ||
|
||
// This offers some additional logic in case the image has a strange | ||
// aspect ratio. For example, a panorama may have a much larger | ||
// width than height. In these cases the total pixels might still | ||
// end up being too large to fit comfortably in memory, so we should | ||
// be more aggressive with sample down the image (=larger inSampleSize). | ||
|
||
val totalPixels = (width * height).toFloat() | ||
|
||
// Anything more than 2x the requested pixels we'll sample down further | ||
val totalReqPixelsCap = (reqWidth * reqHeight * 2).toFloat() | ||
|
||
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { | ||
inSampleSize++ | ||
} | ||
} | ||
return inSampleSize | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters