Skip to content

Instantly share code, notes, and snippets.

@harshmittal2810
Created January 31, 2021 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harshmittal2810/67e03c1a6fe6136a08a80006fc1d29a2 to your computer and use it in GitHub Desktop.
Save harshmittal2810/67e03c1a6fe6136a08a80006fc1d29a2 to your computer and use it in GitHub Desktop.
ImageCompressor with keeping image in exact rotating position
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
)
}
}
}
@harshmittal2810
Copy link
Author

Try to use like this

val originalFile = File(imagePath)
        val compressedFile = ImageCompressor.compressBitmap(context, originalFile)
        Log.e("FileSize",
            "${(compressedFile.length() / 1024).toString().toInt()}, File Name: ${
                Uri.parse(compressedFile.absolutePath).getFileName(context)
            }"
        )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment