从Raspberry Pi(Python)到Android应用程序(Java)的图像传输

2024-04-26 12:52:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经建立了一个客户机-服务器体系结构,这样我的raspberry pi 3可以录制音频,对其进行一些分析,然后将数据(通过TCP)发送到android应用程序以显示在应用程序屏幕上。录音和分析已经完成,我能够使连接和传输字符串数据,显示在应用程序上没有问题。然而,我一直未能成功地将图像从rpi传输到android应用程序。因此,基本上,图像存储在rpi上,我试图将图像传输到应用程序以显示它。我已经在这个工作了一个多星期没有运气,所以任何帮助将不胜感激!你知道吗

我当前的实现(下面提供了所有代码):

在rpi(python)上:如我所说,在android应用程序上发送字符串并显示它们是没有任何问题的。当我发送音频分析的图像部分时,我首先发送一个字符串,上面写着“?start”,这样android端就知道将要发送的是一个图像而不是一个字符串(并将等待更新GUI,直到它接收到整个图像)。然后,我打开存储在rpi上的图像,以字节数组的形式读取整个图像(通常约为40-50k字节)。我得到字节数组的长度,并将其作为字符串发送到android应用程序。最后,我将字节数组发送到android,它等待来自应用程序的OK消息。所有这些工作都不会报告任何错误。你知道吗

在android应用程序(java)上:当应用程序收到“?start”字符串,然后它使用一个缓冲读取器(这是我用来读取之前成功传输到应用程序的字符串数据)来读取图像字节数组的大小。然后,我创建了两个缓冲区,msg\u buff和img\u buff。msg\u buff一次读取1024字节,而img\u buff将保存图像的整个字节数组。在无限while循环中,我有一个DataInputStream,调用In,将字节读入msg\u buff并返回读取的字节数。然后,我将msg\u buff的复制内容连接到img\u buff中。一旦从in读取的字节数为-1或imgèu偏移量(仅为读取的字节总数)大于或等于image bytes数组的大小,while循环就会中断。然后,我将尝试将图像保存到android内部存储,然后稍后将其加载到imageView以显示它。这段代码确实成功地读入了字节,直到还有大约2000-3000个字节要读,然后它似乎冻结了int bytes_read=阅读(消息\u buff,0,消息_浅黄色长度)线路。我还不能通过这一点,所以我不知道如果保存图像到内部存储,然后加载到imageview这种方式也将工作。你知道吗

我也尝试过使用base64编码/解码,但这也会不断产生错误。我试过rpi一次只发送1024字节的图像,但也没有成功。我已经尝试过几种这种方法的实现,但到目前为止没有任何效果。如果有人看错了什么或者有别的办法,我洗耳恭听!你知道吗

Android Studio(应用程序端):

//receives the message which the server sends back
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);

mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));


//in this while the client listens for the messages sent by the server
while (mRun) {

    mServerMessage = mBufferIn.readLine();

    if (mServerMessage != null && mMessageListener != null) {

           //Check if data is image
           if(mServerMessage.equals("?start"))
           {

                 // Get length of image byte array
                 int size = Integer.parseInt(mBufferIn.readLine());


                 // Create buffers
                 byte[] msg_buff = new byte[1024];
                 byte[] img_buff = new byte[size];
                 int img_offset = 0;

                 while(true){
                    int bytes_read = in.read(msg_buff, 0, msg_buff.length);

                    if(bytes_read == -1){ break; }

                    //copy bytes into img_buff
                    System.arraycopy(msg_buff, 0, img_buff, img_offset, bytes_read);
                    img_offset += bytes_read;

                    if( img_offset >= size) { break; }


                 }

                 ContextWrapper cw = new ContextWrapper(ApplicationContextProvider.getContext());
                 File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
                 File mypath = new File(directory, "signal.jpeg");

                 Bitmap bitmap = BitmapFactory.decodeByteArray(img_buff, 0, img_buff.length);
                 FileOutputStream fos = null;

                 try{
                    fos = new FileOutputStream(mypath);

                    //Use compress method on Bitmap object to write image to OutputStream
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);

                    //Send OK
                    byte[] OK = new byte[] {0x4F, 0x4B};
                    sout.write(OK);

                 } catch (Exception e) {
                    e.printStackTrace();
                 }

树莓皮(Python):

def image_to_byte_array(image_file, conn):
    with open(image_file, 'rb') as imageFile:
         content = imageFile.read()
         conn.sendall("?start\n".encode('utf-8'))
         size = len(content)
         strSize = str(size) + "\n"
         conn.sendall(strSize.encode('utf-8'))
         conn.sendall(content)

注意conn是app和rpi之间的连接,图像是PNG。你知道吗

如果有人知道为什么这不起作用,或者有更好的方法让我这样做,我会非常感激!!提前谢谢!!:)


Tags: 字符串图像image应用程序imgnewread字节