Search code examples
androidarrayskotlinbitmap

Converting a bitmap to bytearray to be displayed on an e-paper


so I have to convert a bitmap that is 400x300 into a byte array with exactly 15000 size. It has to be displayed on an e-paper screen so it can only be black/white/gray.

This is my attempt so far:

fun convertPictureToByteArray(bitmap: Bitmap): ByteArray {
        val byteArray = ByteArray(15000)
        var index = 0
        var temp = 0

        val pixels = IntArray(bitmap.width * bitmap.height)
        bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
        for(x in (bitmap.height - 1) downTo 0) {
            for(y in 0 until bitmap.width / 8) {
                var tempPixels = IntArray(8)
                for(z in 0 until 8) {
                    tempPixels[z] = pixels[temp]
                    temp++
                }
                var totalLuminance = 0.0
                for(pixel in tempPixels) {
                    val red = Color.red(pixel)
                    val green = Color.green(pixel)
                    val blue = Color.blue(pixel)

                    val luminance = 0.299 * red + 0.587 * green + 0.114 * blue
                    totalLuminance += luminance
                }

                val averageLuminance = totalLuminance / tempPixels.size
                byteArray[index] = grayShadesArray[averageLuminance.toInt()]
                index++
            }
        }

        return byteArray
    }

Basically what it should do is go through the bitmap pixel by pixel and get average luminance from 8 pixels that are next to each other. Based on the average luminance I get byte value from greyShadesArray with that index and save it to a byte array I return. It kinda works but not well enough. There are white lines and text is not readable: Converted image

Any suggestions on fixing it or other approaches are much appreciated!


Solution

  • As @Selvin suggested I should have checked each pixel by the treshold and converted the binary to hex/byte. Here is the working version:

    fun convertPictureToByteArray(bitmap: Bitmap): ByteArray {
            val byteArray = ByteArray(15000)
            var index = 0
            var temp = 0
    
            val pixels = IntArray(bitmap.width * bitmap.height)
            bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)
            for(x in (bitmap.height - 1) downTo 0) {
                for(y in 0 until bitmap.width / 8) {
                    var tempBinary = ""
                    for(z in 0 until 8) {
                        val red = Color.red(pixels[temp])
                        val green = Color.green(pixels[temp])
                        val blue = Color.blue(pixels[temp])
    
                        val luminance = 0.299 * red + 0.587 * green + 0.114 * blue
                        if(luminance < 128)
                            tempBinary += "0"
                        else
                            tempBinary += "1"
                        temp++
                    }
                    val decimalValue = Integer.parseInt(tempBinary, 2)
                    val hexValue = decimalValue.toString(16).toUpperCase()
                    byteArray[index] = hexValue.toInt(16).toByte()
                    index++
                }
            }
    
            return byteArray
        }