Created
November 4, 2019 12:00
-
-
Save AndSky90/640328d07df18e76f9687e8dd31d4e7a to your computer and use it in GitHub Desktop.
Image compress and rotate
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
object ImageProcessor { | |
private const val MAX_IMAGE_DIMENSION = 1920 | |
private const val COMPRESS_QUALITY = 100 | |
@Throws(IOException::class) | |
fun saveImageWithFixFromUri(context: Context, uri: Uri, filePath: String) { | |
val bitmap = getFixedImageFromUri(context, uri) | |
saveBitmapToFile(bitmap, filePath) | |
} | |
@Throws(IOException::class) | |
private fun getFixedImageFromUri(context: Context, photoUri: Uri): Bitmap { | |
val bmpOptions = | |
BitmapFactory.Options().apply { inSampleSize = getScaleRatioFromUri(context, photoUri) } | |
val inputStream = context.contentResolver.openInputStream(photoUri) | |
val bitmap = BitmapFactory.decodeStream(inputStream, null, bmpOptions)!! | |
inputStream?.close() | |
val degrees = getOrientationFromUri(context, photoUri) | |
return if (degrees > 0) { | |
val output = rotate(bitmap, degrees.toFloat()) | |
bitmap.recycle() | |
output | |
} else bitmap | |
} | |
private fun getScaleRatioFromUri(context: Context, photoUri: Uri): Int { | |
val inputStream = context.contentResolver.openInputStream(photoUri) | |
val boundsOptions = BitmapFactory.Options().apply { inJustDecodeBounds = true } | |
BitmapFactory.decodeStream(inputStream, null, boundsOptions) | |
inputStream?.close() | |
return getScale(boundsOptions) | |
} | |
private fun getOrientationFromUri(context: Context, selectedImage: Uri): Int { | |
val cursor = context.contentResolver.query( | |
selectedImage, | |
arrayOf(MediaStore.Images.ImageColumns.ORIENTATION), null, null, null | |
) | |
return if (cursor?.count != 1) | |
0 | |
else { | |
cursor.moveToFirst() | |
val degrees = cursor.getInt(0) | |
cursor.close() | |
degrees | |
} | |
} | |
fun fixBitmapOrientation(filePath: String?) { | |
if (filePath == null) return | |
val bitmap = getFixedImageFromPath(filePath) | |
saveBitmapToFile(bitmap, filePath) | |
} | |
private fun getFixedImageFromPath(filePath: String): Bitmap { | |
val bmpOptions = | |
BitmapFactory.Options().apply { inSampleSize = getScaleRatioFromPath(filePath) } | |
val bitmap = BitmapFactory.decodeFile(filePath, bmpOptions) | |
val degrees = getOrientationFromPath(filePath) | |
return if (degrees > 0) { | |
val output = rotate(bitmap, degrees.toFloat()) | |
bitmap.recycle() | |
output | |
} else bitmap | |
} | |
private fun getScaleRatioFromPath(filePath: String): Int { | |
val boundsOptions = BitmapFactory.Options().apply { inJustDecodeBounds = true } | |
BitmapFactory.decodeFile(filePath, boundsOptions) | |
return getScale(boundsOptions) | |
} | |
private fun getOrientationFromPath(filePath: String): Int { | |
val exifOrientation = ExifInterface(filePath) | |
.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED) | |
log("ExifInterface ......... orientation = $exifOrientation") | |
return when (exifOrientation) { | |
ExifInterface.ORIENTATION_ROTATE_180 -> 180 | |
ExifInterface.ORIENTATION_ROTATE_90 -> 90 | |
ExifInterface.ORIENTATION_ROTATE_270 -> 270 | |
else -> 0 | |
} | |
} | |
private fun getScale(boundsOptions: BitmapFactory.Options): Int { | |
// Find the correct scale value. It should be the power of 2. | |
var widthTmp = boundsOptions.outWidth | |
var heightTmp = boundsOptions.outHeight | |
val requiredSize = MAX_IMAGE_DIMENSION | |
var scale = 1 | |
while (true) { | |
if (widthTmp / 2 < requiredSize && heightTmp / 2 < requiredSize) break | |
widthTmp /= 2 | |
heightTmp /= 2 | |
scale++ | |
} | |
log("scale of saved image = $scale") | |
return scale | |
} | |
private fun saveBitmapToFile(bitmap: Bitmap, filePath: String) { | |
val os = BufferedOutputStream(FileOutputStream(filePath)) | |
bitmap.compress(Bitmap.CompressFormat.PNG, COMPRESS_QUALITY, os) | |
log("height and width from gallery: ${bitmap.height}, ${bitmap.width}") | |
os.close() | |
} | |
private fun rotate(bitmap: Bitmap, degrees: Float): Bitmap { | |
val matrix = Matrix().apply { postRotate(degrees) } | |
return Bitmap | |
.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) | |
} | |
fun createImageFile(context: Context?): File? { | |
try { | |
val storageDir: File? = context?.getExternalFilesDir(Environment.DIRECTORY_PICTURES) | |
val photoFile = File.createTempFile("Current_user_avatar", ".jpg", storageDir) | |
photoFile.setWritable(true) | |
return photoFile | |
} catch (ex: IOException) { | |
log("Error creating file") | |
} | |
return null | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment