package com.grkj.iscs.util import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas import android.os.Environment import com.bumptech.glide.Glide import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target import com.grkj.iscs.util.log.LogUtil import java.io.ByteArrayOutputStream import java.io.File import java.io.FileOutputStream import java.io.IOException object BitmapUtil { fun bitmapToFile(bitmap: Bitmap, fileName: String): File? { // 创建一个临时文件 val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) if (!storageDir.exists()) { storageDir.mkdirs() } val file = File(storageDir, fileName) return try { // 创建文件输出流 val fos = FileOutputStream(file) // 将 Bitmap 压缩并写入文件 bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos) // 刷新并关闭输出流 fos.flush() fos.close() file } catch (e: IOException) { e.printStackTrace() null } } fun bitmapToByteArray(bitmap: Bitmap, format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG, quality: Int = 100): ByteArray { val stream = ByteArrayOutputStream() // 将 Bitmap 压缩并写入到 ByteArrayOutputStream 中 bitmap.compress(format, quality, stream) // 获取字节数组 return stream.toByteArray() } fun loadBitmapFromUrl(ctx: Context, url: String, callback: (Bitmap?) -> Unit) { try { Glide.with(ctx) .asBitmap() .load(url) .listener(object : RequestListener { override fun onLoadFailed( e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean ): Boolean { Executor.runOnMain { callback(null) } return false } override fun onResourceReady( resource: Bitmap?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean ): Boolean { Executor.runOnMain { callback(resource) } return false } }) .submit() } catch (e: Exception) { e.printStackTrace() Executor.runOnMain { callback(null) } } } fun getResizedBitmapFromMipmap( context: Context, resId: Int, reqWidth: Int, reqHeight: Int ): Bitmap { // First decode with inJustDecodeBounds=true to check dimensions val options = BitmapFactory.Options() options.inJustDecodeBounds = true BitmapFactory.decodeResource(context.resources, resId, options) // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight) // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false val scaledBitmap = BitmapFactory.decodeResource(context.resources, resId, options) // Resize the bitmap if necessary return Bitmap.createScaledBitmap(scaledBitmap, reqWidth, reqHeight, false) } private fun calculateInSampleSize( options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int ): Int { // Raw height and width of image val height = options.outHeight val width = options.outWidth var inSampleSize = 1 if (height > reqHeight || width > reqWidth) { val halfHeight = height / 2 val halfWidth = width / 2 // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2 } } return inSampleSize } fun getResizedBitmapFromDrawable( context: Context, resId: Int, reqWidth: Int, reqHeight: Int ): Bitmap? { val drawable = context.resources.getDrawable(resId) if (drawable == null) { LogUtil.e("Drawable is null for resource ID: $resId") return null } // Create a bitmap with the specified width and height val bitmap = Bitmap.createBitmap(reqWidth, reqHeight, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) // Scale the drawable to fit the bitmap dimensions drawable.setBounds(0, 0, reqWidth, reqHeight) drawable.draw(canvas) return bitmap } }