Skip to content

Instantly share code, notes, and snippets.

@phatnhse
Last active September 8, 2018 12:50
Show Gist options
  • Save phatnhse/523a9b2560c38d940e7c0e5ddeca63d2 to your computer and use it in GitHub Desktop.
Save phatnhse/523a9b2560c38d940e7c0e5ddeca63d2 to your computer and use it in GitHub Desktop.
BitmapUtils for java/android developement (written with Kotlin
object BitmapUtils {
private const val MAX_HEIGHT = 1280.0f
private const val MAX_WIDTH = 1280.0f
fun getScaledBitmap(bm: Bitmap,
bmOriginalWidth: Int,
bmOriginalHeight: Int,
originalWidthToHeightRatio: Double,
originalHeightToWidthRatio: Double,
maxHeight: Int,
maxWidth: Int): Bitmap {
var bm = bm
if (bmOriginalWidth > maxWidth || bmOriginalHeight > maxHeight) {
bm = if (bmOriginalWidth > bmOriginalHeight) {
scaleDeminsFromWidth(bm, maxWidth, bmOriginalHeight, originalHeightToWidthRatio)
} else {
scaleDeminsFromHeight(bm, maxHeight, bmOriginalHeight, originalWidthToHeightRatio)
}
}
return bm
}
private fun scaleDeminsFromHeight(bm: Bitmap,
maxHeight: Int,
bmOriginalHeight: Int,
originalWidthToHeightRatio: Double): Bitmap {
var bm = bm
val newHeight = Math.min(maxHeight.toDouble(), bmOriginalHeight * .75).toInt()
val newWidth = (newHeight * originalWidthToHeightRatio).toInt()
bm = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true)
return bm
}
private fun scaleDeminsFromWidth(bm: Bitmap,
maxWidth: Int,
bmOriginalWidth: Int,
originalHeightToWidthRatio: Double): Bitmap {
var bm = bm
//scale the width
val newWidth = Math.min(maxWidth.toDouble(), bmOriginalWidth * .75).toInt()
val newHeight = (newWidth * originalHeightToWidthRatio).toInt()
bm = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true)
return bm
}
fun compressImage(imagePath: String) {
var scaledBitmap: Bitmap? = null
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
var bmp: Bitmap? = BitmapFactory.decodeFile(imagePath, options)
var actualHeight = options.outHeight
var actualWidth = options.outWidth
var imgRatio = actualWidth.toFloat() / actualHeight.toFloat()
val maxRatio = MAX_WIDTH / MAX_HEIGHT
if (actualHeight > MAX_HEIGHT || actualWidth > MAX_WIDTH) {
if (imgRatio < maxRatio) {
imgRatio = MAX_HEIGHT / actualHeight
actualWidth = (imgRatio * actualWidth).toInt()
actualHeight = MAX_HEIGHT.toInt()
} else if (imgRatio > maxRatio) {
imgRatio = MAX_WIDTH / actualWidth
actualHeight = (imgRatio * actualHeight).toInt()
actualWidth = MAX_WIDTH.toInt()
} else {
actualHeight = MAX_HEIGHT.toInt()
actualWidth = MAX_WIDTH.toInt()
}
}
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight)
options.inJustDecodeBounds = false
options.inDither = false
options.inScaled = false
options.inPurgeable = true
options.inInputShareable = true
options.inPreferredConfig = Bitmap.Config.ARGB_8888
options.inTempStorage = ByteArray(16 * 1024)
try {
bmp = BitmapFactory.decodeFile(imagePath, options)
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565)
} catch (exception: OutOfMemoryError) {
exception.printStackTrace()
}
val ratioX = actualWidth / options.outWidth.toFloat()
val ratioY = actualHeight / options.outHeight.toFloat()
val middleX = actualWidth / 2.0f
val middleY = actualHeight / 2.0f
val scaleMatrix = Matrix()
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY)
if (scaledBitmap == null) {
return
}
val canvas = Canvas(scaledBitmap)
canvas.matrix = scaleMatrix
canvas.drawBitmap(bmp!!, middleX - bmp.width / 2, middleY - bmp.height / 2, Paint(Paint.FILTER_BITMAP_FLAG))
bmp.recycle()
val exif: ExifInterface
try {
exif = ExifInterface(imagePath)
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)
val matrix = Matrix()
when (orientation) {
6 -> matrix.postRotate(90f)
3 -> matrix.postRotate(180f)
8 -> matrix.postRotate(270f)
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.width, scaledBitmap.height,
matrix, true)
val bytes = ByteArrayOutputStream()
scaledBitmap!!.compress(Bitmap.CompressFormat.JPEG, 95, bytes)
val f = File(imagePath)
val fo = FileOutputStream(f)
fo.write(bytes.toByteArray())
fo.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
val height = options.outHeight
val width = options.outWidth
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
}
val totalPixels = (width * height).toFloat()
val totalReqPixelsCap = (reqWidth * reqHeight * 2).toFloat()
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++
}
return inSampleSize
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment