I am trying to send an image from a server to a mobile device using sockets. The server uses python and the client uses kotlin. The image is sent as a byte array and should be saved on the device. I have this code for the server side:
# Open the image
imageSend = Image.open("result.jpg").tobytes()
# Get the size of the byte array
tam_respuesta = len(imageSend)
# Send the size of the image
cliente_socket.sendall(struct.pack('!I', tam_respuesta))
# Send the image
cliente_socket.sendall(imageSend)
And this is the receiving part of the client:
private fun recibirMensaje(socketChannel: SocketChannel): String? {
return try {
// Receive the message size
val tamMensajeBuffer = ByteBuffer.allocate(4)
while (tamMensajeBuffer.hasRemaining()) {
if (socketChannel.read(tamMensajeBuffer) <= 0) {
return null
}
}
tamMensajeBuffer.flip()
val tamMensaje = tamMensajeBuffer.int
Log.d("Conexion", "Se van a recibir $tamMensaje bytes")
// Receive the image data
val dataBuffer = ByteBuffer.allocate(tamMensaje)
while (dataBuffer.hasRemaining()) {
if (socketChannel.read(dataBuffer) <= 0) {
return null
}
}
dataBuffer.flip()
// Check for null array
if(dataBuffer.array() == null){
Log.d("Conexion", "Array is null")
}
// Create a bitmap from the byte array
val bitmap: Bitmap = BitmapFactory.decodeByteArray(dataBuffer.array(), 0, dataBuffer.array().size)
// Path for external storage
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
// Create the file
val imageFile = File(storageDir, "test.jpg")
var outputStream: FileOutputStream? = null
try {
outputStream = FileOutputStream(imageFile)
// Save bitmap as JPG
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
outputStream.flush()
} catch (e: IOException) {
e.printStackTrace()
} finally {
outputStream?.close()
}
// Image saved
"Ok"
} catch (e: Exception) {
Log.d("conexion",e.printStackTrace().toString())
null
}
}
It fails when transforming the byte array to bitmap. The connection itself is stablished and the data is sent. I printed the size of the received array and is the same as the sent one. Also when sending an image it does work, and I can receive strings on the mobile device.
The error I get is:
--- Failed to create image decoder with message 'unimplemented'
java.lang.NullPointerException: decodeByteArray(...) must not be null
at com.example.testsockets.Sockets.recibirMensaje(Sockets.kt:95)
at com.example.testsockets.Sockets.access$recibirMensaje(Sockets.kt:21)
at com.example.testsockets.Sockets$enviarMensaje$1.invokeSuspend(Sockets.kt:57)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
kotlin.Unit
Is as if it does not recognize that array as an image. I tried removing dataBuffer.flip()
but it is the same.