Я пытаюсь отправить фотографию с моего Raspberry Pi с помощью Python 3 на мое Android-устройство.Я делаю это через TCP с Pi в качестве клиента и Android-устройством в качестве моего сервера.Моя цель - отправить файл фотографии с Pi на мое Android-устройство.Мое Android-устройство затем декодировало бы эти данные фотографий, а затем установило их в качестве рисунка для ImageView в моем приложении.Пожалуйста, обратите внимание, что я отправляю изображение размером 200 КБ с разрешением 640x480.
Я пробовал установить, где Pi отправляет текст на мое Android-устройство через TCP, и у меня это получилось.
Далее я попытался отправить фотографию с клиента Python3 на сервер Python3.В этом случае я все еще использовал Pi в качестве своего клиента, а ноутбук MacOS использовал в качестве сервера.Это код, который я в конечном итоге использовал.
Сервер - MAC OS
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 11111 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
f = open('torecv.jpg','wb')
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print('Got connection from', addr)
print("Receiving...")
l = c.recv(1024)
while (l):
print("Receiving...")
f.write(l)
l = c.recv(1024)
f.close()
print("Done Receiving")
c.send(b'Thank you for connecting')
c.shutdown(socket.SHUT_RDWR)
c.close() # Close the connection
Клиент - Pi
import socket # Import socket module
import os
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
host = '192.168.254.194' # Get local machine name
port = 6001 # Reserve a port for your service.
CWD_PATH = os.getcwd()
PATH_TO_IMG_DIR = os.path.join(CWD_PATH, 'img_folder', 'test.jpg')
s.connect((host, port))
#s.send(b'Hello Server!')
f = open(PATH_TO_IMG_DIR,'rb')
print('Sending...')
l = f.read(1024)
while (l):
print('Sending...')
s.send(l)
l = f.read(1024)
f.close()
print("Done Sending")
s.shutdown(socket.SHUT_WR)
print(s.recv(1024))
s.close # Close the socket when done
Используя этот код, я смог перенести фотографию с моего Pi на мой ноутбук MacOS.
Теперь я использовал код здесь как ссылку , чтобы перенести мою фотографию с моего Pi на мое Android-устройство.Вот мой код:
Сервер - Android
class ServerThread implements Runnable {
public void run() {
Socket socket;
try {
Log.e(TAG, "starting the serverthread at port 6001");
serverSocket = new ServerSocket(6001);
} catch (IOException e) {
Log.e(TAG, "exception in creating server socket: ", e);
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
}
}
}
}
class CommunicationThread implements Runnable{
private Socket clientSocket;
private DataInputStream input;//private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
Log.e(TAG, "getting data from the input stream!");
//this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
InputStream in = this.clientSocket.getInputStream();
this.input = new DataInputStream(in);
} catch (IOException e) {
Log.e(TAG, "error in creating data input stream: ", e);
e.printStackTrace();
}
}
public void run() {
Log.e(TAG, "running the code!");
while (!Thread.currentThread().isInterrupted()) {
try {
Log.e(TAG, "parsing the input data stream!");
byte[] data;//String read = input.readLine();
int len= this.input.readInt();
if (len > 0) {
data = new byte[len];
this.input.readFully(data,0,data.length);
}
/*
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] data;
int length = 0;
while ((length = this.input.read(data))!=-1) {
out.write(data,0,length);
}
data=out.toByteArray();
*/
Log.e(TAG, "Updating the UI through a thread!!");
// updateConversationHandler.post(new updateUIThread(data));
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(TAG, "error in reading sent data! ", e);
e.printStackTrace();
}
}
}
}
И чтобы использовать эти классы, я объявил следующее как глобальные переменные:
Thread serverThread = null;
Handler updateConversationHandler;
И в моем onCreate()
у меня есть следующее:
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
Приложение запустится, и сокет будет открыт.Однако, когда я пытаюсь отправить фотографию с моего Pi, я получаю сообщение об ошибке в этом блоке кода:
public void run() {
Log.e(TAG, "running the code!");
while (!Thread.currentThread().isInterrupted()) {
try {
Log.e(TAG, "parsing the input data stream!");
byte[] data;//String read = input.readLine();
int len= this.input.readInt();
if (len > 0) {
data = new byte[len];
this.input.readFully(data,0,data.length);
}
/*
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] data;
int length = 0;
while ((length = this.input.read(data))!=-1) {
out.write(data,0,length);
}
data=out.toByteArray();
*/
Log.e(TAG, "Updating the UI through a thread!!");
// updateConversationHandler.post(new updateUIThread(data));
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e(TAG, "error in reading sent data! ", e);
e.printStackTrace();
}
}
}
class updateUIThread implements Runnable {
private byte[] byteArray;//private String msg;
public updateUIThread(byte[] array){ //public updateUIThread(String str) {
this.byteArray=array; //this.msg = str;
}
@Override
public void run() {
Log.e(TAG, "running the photo update!");
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
ivBed.setImageBitmap(bitmap);//text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
Первоначально строка:
data = new byte[len];
была внеif(len>0)
состояние.Но по какой-то причине Pi отправил отрицательное значение, и, конечно, мы не хотим, чтобы отрицательное значение для переменной len
.Конечно, я столкнулся с ошибкой при попытке создать байтовый массив data
с отрицательной длиной.Затем я помещаю эту строку в условие if.
Однако после того, как я это сделал, я нажал OOM Error в той же строке data = new byte[len];
Process: agict.work.freelance.patientsensor, PID: 15224
java.lang.OutOfMemoryError: Failed to allocate a 1677608328 byte allocation with 6291456 free bytes and 254MB until OOM, max allowed footprint 7797480, growth limit 268435456
У меня есть догадка, что во 2-й ошибке я пытался инициализировать байтмассив со значением, которое на самом деле уже было данными изображения, следовательно, ошибка OOM.
Однако, если я просто возьму первое значение и назначу его как len
, есть вероятность, что яполучить отрицательное число, и код попадет в первую ошибку.
Есть ли шанс, что мне придется что-то подправить, чтобы перенести фотографии с Python3 на Android?У меня такое чувство, что происходит несовпадение форматов.
Опять же, моя цель - отправить файл фотографии из Python3 на мое Android-устройство через TCP.Python3 получит файл, а Android-устройство будет декодировать входные данные, которые он получает, и после декодирования использовать эти данные в качестве объекта для ImageView.