Created
January 31, 2021 15:48
-
-
Save harshmittal2810/67e03c1a6fe6136a08a80006fc1d29a2 to your computer and use it in GitHub Desktop.
ImageCompressor with keeping image in exact rotating position
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 ImageCompressor { | |
/** | |
* This doesn't compress the original image file. | |
* It compresses the bitmap and updates it to the new file and returns from app cache | |
*/ | |
@Throws(Exception::class) | |
fun compressBitmap(context: Context, originalImageFile: File): File { | |
val bitmap = updateDecodeBounds(originalImageFile) | |
val file = context.getPicturesFile(originalImageFile.name) | |
val fOut = FileOutputStream(file) | |
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fOut) | |
fOut.flush() // Not really required | |
fOut.close() // do not forget to close the stream | |
return file | |
} | |
/** | |
* This compress the original file. | |
*/ | |
@Throws(Exception::class) | |
fun compressCurrentBitmapFile(originalImageFile: File) { | |
val bitmap = updateDecodeBounds(originalImageFile) | |
val fOut = FileOutputStream(originalImageFile) | |
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fOut) | |
fOut.flush() // Not really required | |
fOut.close() // do not forget to close the stream | |
bitmap.recycle() //recycle the bitmap | |
} | |
/** | |
* Measure decodeBounds of the bitmap from given File. | |
*/ | |
private fun updateDecodeBounds(imageFile: File): Bitmap { | |
return BitmapFactory.Options().run { | |
inJustDecodeBounds = true | |
BitmapFactory.decodeFile(imageFile.absolutePath, this) | |
val sampleHeight = if (outWidth > outHeight) 900 else 1100 | |
val sampleWidth = if (outWidth > outHeight) 1100 else 900 | |
/** | |
* You can tweak the sizes 900, 1100. | |
* The bigger the number is, the more details you can keep. | |
* The lesser, the lesser quality of details. | |
*/ | |
inSampleSize = min(outWidth / sampleWidth, outHeight / sampleHeight) | |
inJustDecodeBounds = false | |
val bmp = BitmapFactory.decodeFile(imageFile.absolutePath, this) | |
val actualHeight = this.outHeight | |
val actualWidth = this.outWidth | |
val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565) | |
val ratioX = actualWidth / outWidth.toFloat() | |
val ratioY = actualHeight / outHeight.toFloat() | |
val middleX = actualWidth / 2.0f | |
val middleY = actualHeight / 2.0f | |
val scaleMatrix = Matrix() | |
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY) | |
val canvas = Canvas(scaledBitmap) | |
canvas.setMatrix(scaleMatrix) | |
canvas.drawBitmap( | |
bmp, | |
middleX - bmp!!.width / 2, | |
middleY - bmp.height / 2, | |
Paint(Paint.FILTER_BITMAP_FLAG) | |
) | |
bmp.recycle() //recycle the bitmap | |
val exif = ExifInterface(imageFile.absoluteFile) | |
val orientation = | |
exif.getAttributeInt( | |
ExifInterface.TAG_ORIENTATION, | |
ExifInterface.ORIENTATION_UNDEFINED | |
) | |
val matrix = Matrix() | |
when (orientation) { | |
ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f) | |
ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f) | |
ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f) | |
} | |
Bitmap.createBitmap( | |
scaledBitmap, | |
0, | |
0, | |
scaledBitmap.width, | |
scaledBitmap.height, | |
matrix, | |
true | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try to use like this