-
-
Save phillies/830f52b0bf592c32fc507669694f66d8 to your computer and use it in GitHub Desktop.
fun floatArrayToGrayscaleBitmap ( | |
floatArray: FloatArray, | |
width: Int, | |
height: Int, | |
alpha :Byte = (255).toByte(), | |
reverseScale :Boolean = false | |
) : Bitmap { | |
// Create empty bitmap in RGBA format (even though it says ARGB but channels are RGBA) | |
val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) | |
val byteBuffer = ByteBuffer.allocate(width*height*4) | |
// mapping smallest value to 0 and largest value to 255 | |
val maxValue = floatArray.maxOrNull() ?: 1.0f | |
val minValue = floatArray.minOrNull() ?: 0.0f | |
val delta = maxValue-minValue | |
var tempValue :Byte | |
// Define if float min..max will be mapped to 0..255 or 255..0 | |
val conversion = when(reverseScale) { | |
false -> { v: Float -> ((v-minValue)/delta*255).toInt().toByte() } | |
true -> { v: Float -> (255-(v-minValue)/delta*255).toInt().toByte() } | |
} | |
// copy each value from float array to RGB channels and set alpha channel | |
floatArray.forEachIndexed { i, value -> | |
tempValue = conversion(value) | |
byteBuffer.put(4*i, tempValue) | |
byteBuffer.put(4*i+1, tempValue) | |
byteBuffer.put(4*i+2, tempValue) | |
byteBuffer.put(4*i+3, alpha) | |
} | |
bmp.copyPixelsFromBuffer(byteBuffer) | |
return bmp | |
} |
You have to make sure your input parameter have matching sizes. An IndexOutOfBoundsException can occur in the loop lines 26-32 if the floatArray
contains more than width
xheight
entries. Check floatArray.size == (width*height)
before calling the function.
The final bitmap is returing black and white. The area of object detected is showing in white color and rest area showing black. Could you please help with this.
The function maps the smallest value in your floatArray
to 0 (black) and the largest value to 255
(white). If you want to have it the other way round, so the smallest value is white and the largest are black, then reverseScale
should be true.
I assume that your object detection function delivers a float array where background is 0
and detected objects are >0
, so if you want to have the detected objects in black and the background in white set reverseScale=true
then calling the function.
SomeThing Like This:
AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.cameraa, PID: 15280
java.lang.IndexOutOfBoundsException: index=264196 out of bounds (limit=264196)
at java.nio.Buffer.checkIndex(Buffer.java:556)
at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:279)
at com.example.cameraa.MainActivity.onCreate$lambda-2(MainActivity.kt:123)
at com.example.cameraa.MainActivity.$r8$lambda$2jojTiyhKvSV11AyQ-LBlWnMfGU(Unknown Source:0)
at com.example.cameraa.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)