kotlin图片合成和压缩

发布于:2024-03-10 ⋅ 阅读:(78) ⋅ 点赞:(0)

kotlin图片合成和压缩

之前的方法是继承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()
            }
        }
    }

网站公告

今日签到

点亮在社区的每一天
去签到