BitmapUtil.kt 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package com.grkj.iscs.util
  2. import android.content.Context
  3. import android.graphics.Bitmap
  4. import android.graphics.BitmapFactory
  5. import android.graphics.Canvas
  6. import android.os.Environment
  7. import com.bumptech.glide.Glide
  8. import com.bumptech.glide.load.DataSource
  9. import com.bumptech.glide.load.engine.GlideException
  10. import com.bumptech.glide.request.RequestListener
  11. import com.bumptech.glide.request.target.Target
  12. import com.grkj.iscs.util.log.LogUtil
  13. import java.io.ByteArrayOutputStream
  14. import java.io.File
  15. import java.io.FileOutputStream
  16. import java.io.IOException
  17. object BitmapUtil {
  18. fun bitmapToFile(bitmap: Bitmap, fileName: String): File? {
  19. // 创建一个临时文件
  20. val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
  21. if (!storageDir.exists()) {
  22. storageDir.mkdirs()
  23. }
  24. val file = File(storageDir, fileName)
  25. return try {
  26. // 创建文件输出流
  27. val fos = FileOutputStream(file)
  28. // 将 Bitmap 压缩并写入文件
  29. bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
  30. // 刷新并关闭输出流
  31. fos.flush()
  32. fos.close()
  33. file
  34. } catch (e: IOException) {
  35. e.printStackTrace()
  36. null
  37. }
  38. }
  39. fun bitmapToByteArray(bitmap: Bitmap, format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG, quality: Int = 100): ByteArray {
  40. val stream = ByteArrayOutputStream()
  41. // 将 Bitmap 压缩并写入到 ByteArrayOutputStream 中
  42. bitmap.compress(format, quality, stream)
  43. // 获取字节数组
  44. return stream.toByteArray()
  45. }
  46. fun loadBitmapFromUrl(ctx: Context, url: String, callback: (Bitmap?) -> Unit) {
  47. try {
  48. Glide.with(ctx)
  49. .asBitmap()
  50. .load(url)
  51. .listener(object : RequestListener<Bitmap> {
  52. override fun onLoadFailed(
  53. e: GlideException?,
  54. model: Any?,
  55. target: Target<Bitmap>?,
  56. isFirstResource: Boolean
  57. ): Boolean {
  58. Executor.runOnMain {
  59. callback(null)
  60. }
  61. return false
  62. }
  63. override fun onResourceReady(
  64. resource: Bitmap?,
  65. model: Any?,
  66. target: Target<Bitmap>?,
  67. dataSource: DataSource?,
  68. isFirstResource: Boolean
  69. ): Boolean {
  70. Executor.runOnMain {
  71. callback(resource)
  72. }
  73. return false
  74. }
  75. })
  76. .submit()
  77. } catch (e: Exception) {
  78. e.printStackTrace()
  79. Executor.runOnMain {
  80. callback(null)
  81. }
  82. }
  83. }
  84. fun getResizedBitmapFromMipmap(
  85. context: Context,
  86. resId: Int,
  87. reqWidth: Int,
  88. reqHeight: Int
  89. ): Bitmap {
  90. // First decode with inJustDecodeBounds=true to check dimensions
  91. val options = BitmapFactory.Options()
  92. options.inJustDecodeBounds = true
  93. BitmapFactory.decodeResource(context.resources, resId, options)
  94. // Calculate inSampleSize
  95. options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
  96. // Decode bitmap with inSampleSize set
  97. options.inJustDecodeBounds = false
  98. val scaledBitmap = BitmapFactory.decodeResource(context.resources, resId, options)
  99. // Resize the bitmap if necessary
  100. return Bitmap.createScaledBitmap(scaledBitmap, reqWidth, reqHeight, false)
  101. }
  102. private fun calculateInSampleSize(
  103. options: BitmapFactory.Options,
  104. reqWidth: Int,
  105. reqHeight: Int
  106. ): Int {
  107. // Raw height and width of image
  108. val height = options.outHeight
  109. val width = options.outWidth
  110. var inSampleSize = 1
  111. if (height > reqHeight || width > reqWidth) {
  112. val halfHeight = height / 2
  113. val halfWidth = width / 2
  114. // Calculate the largest inSampleSize value that is a power of 2 and keeps both
  115. // height and width larger than the requested height and width.
  116. while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
  117. inSampleSize *= 2
  118. }
  119. }
  120. return inSampleSize
  121. }
  122. fun getResizedBitmapFromDrawable(
  123. context: Context,
  124. resId: Int,
  125. reqWidth: Int,
  126. reqHeight: Int
  127. ): Bitmap? {
  128. val drawable = context.resources.getDrawable(resId)
  129. if (drawable == null) {
  130. LogUtil.e("Drawable is null for resource ID: $resId")
  131. return null
  132. }
  133. // Create a bitmap with the specified width and height
  134. val bitmap = Bitmap.createBitmap(reqWidth, reqHeight, Bitmap.Config.ARGB_8888)
  135. val canvas = Canvas(bitmap)
  136. // Scale the drawable to fit the bitmap dimensions
  137. drawable.setBounds(0, 0, reqWidth, reqHeight)
  138. drawable.draw(canvas)
  139. return bitmap
  140. }
  141. }