Java – Uploading an image to the server corrupts the image

Uploading an image to the server corrupts the image… here is a solution to the problem.

Uploading an image to the server corrupts the image

I have an image upload method in my app that needs to send the image and string to my server.

The problem is that the server receives the content (images and strings), but when it saves the image on disk it is corrupted and cannot be opened.

This is the relevant part of the script.

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);

I can’t change the server because other clients use it and it works for them. I just need to understand the cause of image corruption.

Solution

When you execute a new String(byteArray), it converts the binary to the default character set (usually UTF-8). Most character sets are not suitable encodings for binary data. In other words, if you were to encode some binary strings to UTF-8 and then decode them back to binary, you wouldn’t get the same binary strings.

Because you are using multipart encoding, you need to write directly to the entity stream. Apache HTTP clients have assistants to do this. See this guide , or this Android guide to use multipart upload.

If you only need to use strings, you can safely convert a byte array to a string

String byteStr = android.util.Base64.encode(byteArray, android.util.Base64.DEFAULT);

However, it should be noted that your server needs to Base64 decode the string back into a byte array and save it to the image. In addition, the transfer size will be larger because Base64 encoding is not as space-efficient as the original binary.

Related Problems and Solutions