之前的方法是继承AsyncTask 在doInBackground 里面去做压缩的操作,然后用 publishProgress 切到主线程里面更新
新方法是在协程里的去做
class ImageService {
private fun getSumWidths(bitmaps: ArrayList<Bitmap>): Int {
var sumWidth = 0
for (b in bitmaps) {
sumWidth = intValidCheck((sumWidth + b.width).toLong())
}
return sumWidth
}
private fun getMaxHeights(bitmaps: ArrayList<Bitmap>): Int {
var max = bitmaps[0].height
for (bitmap in bitmaps) {
if (max < bitmap.height) {
max = bitmap.height
}
}
return max
}
/**
* crop front rear left right View Image
*/
fun cropImage(src: Bitmap): Bitmap {
Log.d("cropImage src width: " + src.width + ", height: " + src.height)
//int x, int y, int width, int height
val result =
Bitmap.createBitmap(src, 0, 0, CROP_IMAGE_WIDTH_SIZE, CROP_IMAGE_HEIGHT_SIZE)
Log.d("cropImage result width: " + result.width + ", height: " + result.height)
if (result != src) {
src.recycle()
}
return result
}
fun cropOtherViewImage(src: Bitmap): Bitmap? {
Log.d("cropTopViewImage width: " + src.width + ", height: " + src.height)
//int x, int y, int width, int height
val result = Bitmap.createBitmap(
src,
CROP_OTHER_VIEW_IMAGE_X_POINT,
0,
CROP_OTHER_VIEW_IMAGE_WIDTH_SIZE,
CROP_OTHER_VIEW_IMAGE_HEIGHT_SIZE
)
Log.d("cropTopViewImage result width: " + result.width + ", height: " + result.height)
if (result != src) {
src.recycle()
}
return result
}
fun mergeMultipleImages(bitmaps: ArrayList<Bitmap>): Bitmap? {
Log.d("mergeMultipleImages")
if (bitmaps.isEmpty()){
return null
}
var totalWidth = 0
var maxHeight = 0
for (bitmap in bitmaps) {
totalWidth += bitmap.width
if (bitmap.height > maxHeight) {
maxHeight = bitmap.height
}
}
val mergedBitmap = Bitmap.createBitmap(
getSumWidths(bitmaps),
getMaxHeights(bitmaps),
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(mergedBitmap)
val paint = Paint()
/*val mTextPaint = Paint()
mTextPaint.color = Color.WHITE
mTextPaint.isAntiAlias = true*/
var currentX = 0
for (i in bitmaps.indices) {
val bitmap = bitmaps[i]
Log.d("bitmaps.get( " + i + " ) result width: " + bitmap.width + ", height: " + bitmap.height)
val srcRect = Rect(0, 0, bitmap.width, bitmap.height)
val dstRect = Rect(currentX, 0, currentX + bitmap.width, maxHeight)
canvas.drawBitmap(bitmap, srcRect, dstRect, paint)
currentX += bitmap.width
}
Log.d("mergeMultipleImages result Bitmap width: " + mergedBitmap.width + ", height: " + mergedBitmap.height)
return mergedBitmap
}
suspend fun compressImages(bitmap: Bitmap): ByteArray? {
return withContext(Dispatchers.Default) {
Log.d(" start compressImages: ")
val outputStream = ByteArrayOutputStream()
var quality = 100
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
while (outputStream.size() / KB > MAX_IMAGE_SIZE && quality > 0) {
outputStream.reset()
quality -= 1
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
}
Log.d("compressImages:end ${outputStream.size()}")
val saveCompressImage = saveCompressImage(
getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
outputStream
)
Log.d("saveCompressImage: $saveCompressImage")
outputStream.toByteArray()
}
}
private fun saveCompressImage(f: File, bos: ByteArrayOutputStream?): Boolean {
val file = File(f,"compress.jpeg")
Log.d("saveCompressImage : " + file.path)
return try {
val fos = FileOutputStream(file)
bos?.writeTo(fos)
Log.d("saveCompressImage success")
fos.flush()
fos.close()
true
} catch (e: Exception) {
Log.d("saveCompressImage error")
e.printStackTrace()
false
}
}
companion object {
private const val MAX_IMAGE_SIZE = 250
private const val CROP_IMAGE_WIDTH_SIZE = 120 // 尺寸要保持一致
private const val CROP_IMAGE_HEIGHT_SIZE = 121 // 尺寸要保持一致
private const val CROP_OTHER_VIEW_IMAGE_X_POINT = 1288 // 其他的尺寸要保持一致 这个是额外添加的view
private const val CROP_OTHER_VIEW_IMAGE_WIDTH_SIZE = 632 // 其他的尺寸要保持一致
private const val CROP_OTHER_VIEW_IMAGE_HEIGHT_SIZE = 720 其他的尺寸
private const val KB: Long = 1024
fun intValidCheck(value: Long): Int {
if (value < Int.MIN_VALUE || value > Int.MAX_VALUE) {
throw ArithmeticException("Integer overflow")
}
return value.toInt()
}
}
}