73 lines
2.6 KiB
Kotlin
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)
|
|
}
|
|
}
|
|
}
|