在我正在构建的Android应用程序中,我使用Base64.encodeToString()将jpg图像转换为字符串,并通过TCP套接字发送到服务器。
问题是当我尝试将字符串解码回图像时。 我可以打印我收到的字符串,它在文件的末尾看起来像这样(我可以复制的唯一部分,因为文件很大,可以在终端上打印所有内容):
....+77DgjRKHqbxBmYCDOzv9vLzFwff4N146snCWin6ZlzbN++HJOIIPodB/JTOoc1NjczeqoHwOju
iWdI6ePeSO0ADz46vh4LODnM7FCJYhbTX0TizmNatXvxSFoVzLiqfn19iYjvAPD/AQnRoUxtpJij
AAAAAElFTkSuQmCC
但是当我尝试解码并再次保存到jpg文件时,我收到以下错误:
Traceback (most recent call last):
File "tcp.py", line 20, in <module>
file.write(base64.decodestring(msg))
File "/usr/lib/python2.7/base64.py", line 328, in decodestring
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
以下是我用于编码和发送消息的Android应用程序代码:
//Function that encodes the Bitmapfile into string
public String BitMapToString(Bitmap bitmap){
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
byte [] arr=baos.toByteArray();
String result=Base64.encodeToString(arr, Base64.DEFAULT);
return result;
}
class myTask extends AsyncTask<Void,Void,Void>
{
//Faz a conexao entre aparelho e servidor
@Override
protected Void doInBackground(Void... params){
try
{
//create socket and buffer to send the string message
newSocket = new Socket(ipAdress,5000);
printWriter = new PrintWriter(newSocket.getOutputStream());
bufferedWriter = new BufferedWriter(new OutputStreamWriter(newSocket.getOutputStream()));
//Reads the internal storage image and converts into string using Base64
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM+"/Reccoon3D/123.jpg");
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
message = BitMapToString(bitmap); //encodes the bitmap
//sends the enconded image
bufferedWriter.write(message);
bufferedWriter.flush();
bufferedWriter.close();
newSocket.close();
}catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
这是我的python代码,它接收消息并尝试将其解码为image:
import socket
import base64
host = '192.168.1.16'
port = 5000
tcp=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
orig = (host,port)
tcp.bind(orig)
tcp.listen(1)
file=open('file.png','wb')
while True:
con, client = tcp.accept()
print('Conected by', client)
while True:
msg = con.recv(1024000) #Initially 1024 but changet so the message
#would not be sliced into pieces
if not msg: break
#print(msg)
file.write(base64.decodestring(msg))
print('Finalizado com sucesso')
con.close
答案 0 :(得分:0)
msg = con.recv(1024000) #Initially 1024 but changet so the message
这将从套接字读取最多 1024000字节。它可能不会这样。并且,使用recv
读取的块的大小不需要与对等方写入的块的大小有任何关联,除了读取所有recv
的总大小与总大小相匹配发送。
file.write(base64.decodestring(msg))
base64字符串的大小始终是4个字节的倍数。即使解码数据只是一个字节,编码字符串也将是4个字节:2编码输入,2&#39; =&#39;用于填充。如果与decodestring
一起使用的字符串长度不是4的倍数,则会假设填充不良,即提升binascii.Error: Incorrect padding
。
您的代码盲目地假设msg
的长度始终是4的倍数,因为您假设recv
将返回发送的所有数据。但是,这个假设是错误的,如果msg
的长度不是4的倍数,你会得到你看到的错误。
答案 1 :(得分:0)
我在做和你说的完全一样的事情。
在我正在构建的android应用程序中,我将jpg图像转换为 字符串使用Base64.encodeToString()并通过TCP发送到服务器 套接字。
我终于明白了。
首先,我将其用作模板this项目。在这里,您可以进行捕捉,然后将其作为BitMap加载。然后,您必须将其转换为编码为PNG文件的字节数组,然后通过base64算法(已在Java中实现)对其进行编码。
然后,我用python和其他一些东西制作了一个套接字服务器来处理传输。获得编码字符串后,只需解码它,并将结果字符串另存为.png文件,然后使用cv2.imread()
和Vuala加载它即可。
如果要检查我的工作方式,这是我的项目: Android side Python side