Runt
2025-04-13 8c0f96b20f4cf44d230b373f51261566af02de8e
app/src/main/java/com/runt/live/util/BitmapUtils.kt
@@ -3,9 +3,11 @@
import android.content.ContentResolver
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ImageFormat
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Rect
import android.media.ExifInterface
import android.media.Image
@@ -18,11 +20,13 @@
import android.renderscript.ScriptIntrinsicYuvToRGB
import android.renderscript.Type
import android.util.Log
import android.view.SurfaceHolder
import androidx.annotation.OptIn
import androidx.camera.core.ExperimentalGetImage
import androidx.camera.core.ImageProxy
import java.io.IOException
import java.nio.ByteBuffer
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.min
@@ -683,5 +687,95 @@
        }
    }
    fun textToBitmap(text : String , textSize : Float , textColor : Int , bgColor : Int) : Bitmap { // 创建 Paint 对象设置文本参数
        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint.textSize = textSize.toFloat()
        paint.color = textColor
        val fontMetrics = paint.fontMetrics
        val lineHeight : Float = fontMetrics.bottom - fontMetrics.top + 30
        // 按换行符分割文本
        val lines  = text.split("\n")
        // 计算最大宽度
        var maxWidth = 0f
        for (line in lines) {
            val width = paint.measureText(line)
            if (width > maxWidth) maxWidth = width
        }
        // 创建 Bitmap
        val bmpWidth = ceil(maxWidth.toDouble()).toInt()
        val bmpHeight = ceil((lineHeight * lines.size).toDouble()).toInt()
        val bitmap = Bitmap.createBitmap(bmpWidth , bmpHeight , Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        canvas.drawColor(bgColor) // 背景色
        // 逐行绘制文本
        var y = - fontMetrics.top
        for (line in lines) {
            canvas.drawText(line !! , 0f , y , paint)
            y += lineHeight
        }
        return bitmap
    }
    fun argbToNV21(argb : IntArray , width : Int , height : Int) : ByteArray {
        val yuv = ByteArray(width * height * 3 / 2)
        val frameSize = width * height
        var yIndex = 0
        var uvIndex = frameSize
        for (j in 0 until height) {
            for (i in 0 until width) {
                val argbIndex = j * width + i
                val color = argb[argbIndex]
                val r = (color shr 16) and 0xFF
                val g = (color shr 8) and 0xFF
                val b = color and 0xFF
                // RGB to YUV conversion
                val y = ((66 * r + 129 * g + 25 * b + 128) shr 8) + 16
                val u = ((- 38 * r - 74 * g + 112 * b + 128) shr 8) + 128
                val v = ((112 * r - 94 * g - 18 * b + 128) shr 8) + 128
                yuv[yIndex ++] = max(0.0 , min(255.0 , y.toDouble())).toInt().toByte()
                // 每 2x2 像素写一次 UV
                if ((j % 2 == 0) && (i % 2 == 0)) {
                    yuv[uvIndex ++] = max(0.0 , min(255.0 , v.toDouble())).toInt().toByte()
                    yuv[uvIndex ++] = max(0.0 , min(255.0 , u.toDouble())).toInt().toByte()
                }
            }
        }
        return yuv
    }
    fun cavansSurface(surfaceHolder : SurfaceHolder ,bitmap : Bitmap){
        var canvas : Canvas? = null;
        try {
            canvas = surfaceHolder.lockCanvas()
            if (canvas != null) {
                var src = Rect(0,0,bitmap.width,bitmap.height)
                var des = Rect(0,0,surfaceHolder.surfaceFrame.width(),surfaceHolder.surfaceFrame.height())
                canvas.drawBitmap(bitmap,src,des,null)
            }
        } catch (e : Exception) {
            Log.e("Surface" , "绘制失败:" + e.message)
        } finally {
            if (canvas != null) {
                surfaceHolder.unlockCanvasAndPost(canvas)
            }
        }
    }
}