Files
student_recognize/app/src/main/java/com/example/studentfaceregistry/ImageUtils.kt
2026-08-07 16:06:43 +08:00

73 lines
2.6 KiB
Kotlin

package com.example.studentfaceregistry
import android.graphics.Bitmap
import android.graphics.Matrix
import android.media.Image
import androidx.camera.core.ExperimentalGetImage
import androidx.camera.core.ImageProxy
@ExperimentalGetImage
object ImageUtils {
fun imageProxyToBitmap(imageProxy: ImageProxy, applyRotation: Boolean = true): Bitmap {
val image = imageProxy.image ?: error("ImageProxy does not contain an image.")
val bitmap = yuv420ToBitmap(image)
if (!applyRotation || imageProxy.imageInfo.rotationDegrees == 0) {
return bitmap
}
val matrix = Matrix().apply {
postRotate(imageProxy.imageInfo.rotationDegrees.toFloat())
}
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
private fun yuv420ToBitmap(image: Image): Bitmap {
val width = image.width
val height = image.height
val yPlane = image.planes[0]
val uPlane = image.planes[1]
val vPlane = image.planes[2]
val yBuffer = yPlane.buffer
val uBuffer = uPlane.buffer
val vBuffer = vPlane.buffer
val pixels = IntArray(width * height)
val yRowStride = yPlane.rowStride
val yPixelStride = yPlane.pixelStride
val uRowStride = uPlane.rowStride
val uPixelStride = uPlane.pixelStride
val vRowStride = vPlane.rowStride
val vPixelStride = vPlane.pixelStride
var pixelIndex = 0
for (row in 0 until height) {
val yRow = row * yRowStride
val uvRow = (row shr 1) * uRowStride
val vvRow = (row shr 1) * vRowStride
for (col in 0 until width) {
val y = (yBuffer.get(yRow + col * yPixelStride).toInt() and 0xFF) - 16
val u = (uBuffer.get(uvRow + (col shr 1) * uPixelStride).toInt() and 0xFF) - 128
val v = (vBuffer.get(vvRow + (col shr 1) * vPixelStride).toInt() and 0xFF) - 128
val y1192 = 1192 * y.coerceAtLeast(0)
var r = y1192 + 1634 * v
var g = y1192 - 833 * v - 400 * u
var b = y1192 + 2066 * u
r = r.coerceIn(0, 262143)
g = g.coerceIn(0, 262143)
b = b.coerceIn(0, 262143)
pixels[pixelIndex++] = -0x1000000 or
((r shl 6) and 0x00FF0000) or
((g shr 2) and 0x0000FF00) or
((b shr 10) and 0x000000FF)
}
}
return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).apply {
setPixels(pixels, 0, width, 0, 0, width, height)
}
}
}