| | |
| | | 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 |
| | |
| | | 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 |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | 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) |
| | | } |
| | | } |
| | | } |
| | | } |