это часть анализатора camerax для вращения изображения: буфер y передается в метод set, а отдельные байты считываются через метод get или оператор []
private data class IImage(var byteArray: ByteArray= ByteArray(0), var width: Int=0, var height: Int=0)
{
//set rotationDegrees to 0 to disable rotation
fun Set(rotationDegrees:Int,buffer:ByteBuffer,w:Int,h:Int){
if (byteArray.size != buffer.capacity()) byteArray =ByteArray(buffer.capacity()) //resize buffer
if(rotationDegrees == 0 || rotationDegrees % 90 != 0){ buffer.get(byteArray); width=w; height=h}
else
{
for (y in 0 until h) // we scan the array by rows
for (x in 0 until w)
when (rotationDegrees) {
90 -> byteArray[x * h + h - y - 1] = buffer.get(x + y * w) // Fill from top-right toward left (CW)
180 -> byteArray[w * (h - y - 1) + w - x - 1] = buffer.get(x + y * w) // Fill from bottom-right toward up (CW)
270 -> byteArray[y + x * h] = buffer.get(y * w + w - x - 1) // The opposite (CCW) of 90 degrees
}
if (rotationDegrees != 180) { height = w; width = h }
}
}
}
, и это тот же код, но с использованием дополнительного ByteArray
private data class IImage2(var byteArray: ByteArray= ByteArray(0), var width: Int=0, var height: Int=0)
{
//set rotationDegrees to 0 to disable rotation
fun Set(rotationDegrees:Int,buffer:ByteBuffer,w:Int,h:Int){
if (byteArray.size != buffer.capacity()) byteArray =ByteArray(buffer.capacity()) //resize buffer
buffer.get(byteArray); width=w; height=h
if(rotationDegrees == 0 || rotationDegrees % 90 != 0) return
else
{
val tByteArray=ByteArray(byteArray.size)
for (y in 0 until h) // we scan the array by rows
for (x in 0 until w)
when (rotationDegrees) {
90 -> tByteArray[x * h + h - y - 1] = byteArray[x + y * w] // Fill from top-right toward left (CW)
180 -> tByteArray[w * (h - y - 1) + w - x - 1] = byteArray[x + y * w] // Fill from bottom-right toward up (CW)
270 -> tByteArray[y + x * h] = byteArray[y * w + w - x - 1] // The opposite (CCW) of 90 degrees
}
byteArray=tByteArray
if (rotationDegrees != 180) { height = w; width = h }
}
}
}
класс анализа хранит один экземпляр IImage или IImage2, код IImage дает 5: 7 к / с, а IImage - 9/10: 12 к / с последовательно на эмуляторе, почему создание другого ByteArray и копирование данных в 2 раза быстрее, чем доступ к отдельным байтам ByteBuffer