I want to send an image from my android device to python through sockets, I've been successful in sending text from Android-Python. When I send the image I get the toast of the image being sent but on the receiving end the image is corrupted with a 0 KB size I appreciate any help, as I'm currently stuck here.
Here is my code
image.py
from socket import *
port = 8888
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', port))
s.listen(1) #listens to 1 connection
conn, addr = s.accept()
print("Connected by the ",addr)
while True:
data = conn.recv(1024)
with open('image.jpg', 'wb') as file:
file.write(data)
conn.close()
The Android side code is,
public void send(View v) {
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(i, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
try {
final Uri imageUri = data.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
imageView.setImageBitmap(selectedImage);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
selectedImage.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] array = byteArrayOutputStream.toByteArray();
SendImageClient sendImageClient = new SendImageClient();
sendImageClient.execute(array);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "no image selected", Toast.LENGTH_SHORT).show();
}
}
public class SendImageClient extends AsyncTask<byte[], Void, Void> {
@Override
protected Void doInBackground(byte[]... voids) {
try {
Socket socket= new Socket("192.168.0.106",8888);
OutputStream out=socket.getOutputStream();
DataOutputStream dataOutputStream=new DataOutputStream(out);
dataOutputStream.writeInt(voids[0].length);
dataOutputStream.write(voids[0],0,voids[0].length);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Image sent", Toast.LENGTH_SHORT).show();
}
});
dataOutputStream.close();
out.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Your python code is truncating the output file on every run of the loop. On the last run, when the connection is closed, the file is truncated, conn.recv
will return an empty string, and nothing else will be written to the file.
Move with open(..)
outside the loop that reads from the socket, and handle the connection closing so you don't have an infinite loop:
with open('image.jpg', 'wb') as file:
while True:
data = conn.recv(1024)
if not data: break
file.write(data)
Your java code is sending the size of the data it's sending before the data itself - you should either remove this or adjust the python code to take this into account.
dataOutputStream.writeInt(voids[0].length);
dataOutputStream.write(voids[0],0,voids[0].length);