将图像上传到服务器会破坏图像

时间:2016-03-07 22:39:14

标签: java android

我的应用程序中有一个图像上传方法,需要将图像和字符串发送到我的服务器。

问题是服务器接收内容(图像和字符串),但是当它将图像保存在磁盘上时,它已损坏并且无法打开。

这是剧本的相关部分。

HttpPost httpPost = new HttpPost(url);

Bitmap bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();

bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);

byte[] byteArray = stream.toByteArray();
String byteStr = new String(byteArray);

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("--"+boundary+"\r\n");
stringBuilder.append("Content-Disposition: form-data; name=\"content\"\r\n\r\n");
stringBuilder.append(message+"\r\n");

stringBuilder.append("--"+boundary+"\r\n");
stringBuilder.append("Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n");

stringBuilder.append("Content-Type: image/jpeg\r\n\r\n");

stringBuilder.append(byteStr);
stringBuilder.append("\r\n");

stringBuilder.append("--"+boundary+"--\r\n");
StringEntity entity = new StringEntity(stringBuilder.toString());
httpPost.setEntity(entity);

我无法更改服务器,因为其他客户端使用它并且它适用于它们。我只需要了解图像被破坏的原因。

2 个答案:

答案 0 :(得分:3)

执行new String(byteArray)时,它会将二进制文件转换为默认字符集(通常为UTF-8)。大多数字符集不适合二进制数据。换句话说,如果您要将某些二进制字符串编码为UTF-8然后解码回二进制,则不会得到相同的二进制字符串。

由于您使用的是多部分编码,因此需要直接写入实体流。 Apache HTTP Client有助手执行此操作。 See this guidethis Android guide上传多部分。

如果您只需要使用字符串,则可以使用

安全地将字节数组转换为字符串
String byteStr = android.util.Base64.encode(byteArray, android.util.Base64.DEFAULT);

但重要的是要注意,您的服务器需要Base64将字符串解码回字节数组并将其保存到图像中。此外,传输大小将更大,因为Base64编码不像原始二进制文件那样节省空间。

答案 1 :(得分:0)

由于您使用的是new String(byteArray),因此上述解决方案无效。构造函数使用默认编码对字节数组进行编码 - 请参阅What is the default encoding - 很可能您的数据中的字节序列无法编码为字符。

更准确地说,字符集定义字符如何表示为字节。 大多数字符集都有超过256个字符。这就是为什么你需要多个字节来表示一个字符。 UTF-8和UTF-16最多使用四个字节。 所以你在数字空间和字符空间之间有一个映射,这个映射不是先验的。因此很可能在数字空间中存在一个没有字符映射到它的数字。

建议的解决方案@Samuel是万无一失的,因为Base64使用A-Z,a-z,0-9,+,/并以=结尾来表示一个字节。我更喜欢这个解决方案!

如果您不想或不能使用Base64,那么您可以尝试将每个字节放入StringBuilder中,希望服务器在获取之前不进行任何编码。

for (byte b : byteArray) {
  stringBuilder.append((char)b);
}

我一般不推荐这个解决方案,但它可以帮助你完成你的工作。