0

I have been hitting my head against a wall on this one.

In my Android App, I select an image. That all seems to be working fine. I then convert it to a byte array and HTTP POST it to a server. The data written to file on the server side does not appear to be what the data started as.

When checking things end-to-end it seems that the file on my device is 1,066,896 bytes. The data on the server is 14,745,600 bytes.

Code from Selecting the Image:

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case PICK_IMAGE: {
            if (resultCode != RESULT_OK)
                return;

            Uri selectedImage = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);

                MainActivityFragment fragment = (MainActivityFragment)Fragments.Get("Main");

                new SendPic().execute(bitmap);
            } catch (IOException exception) {
                Log.e(TAG, "Could not load image", exception);
            }

            break;
        }
    }
}

If I check bitmap.getByteCount() in the above code, it will report 14,745,600, which makes me relatively confident that the data being sent to the server is good. But I can't figure out while the data read in is 14x larger than what I show on the device. It I take this same bitmap though, and apply it to an ImageView, the image looks just fine.

SendPic is a simple class that extends AsyncTask. No magic there.

public static String SendHttpImage(String path, Bitmap bitmap, String name, String filename) {
    String attachmentName = "bitmap";
    String attachmentFileName = "bitmap.bmp";
    String crlf = "\r\n";
    String twoHyphens = "--";
    String boundary = "******";

    try {
        String url = "http://server.com/index.php?" + path;
        URL u = new URL(url);
        HttpURLConnection urlConnection = (HttpURLConnection)u.openConnection();
        urlConnection.setUseCaches(false);
        urlConnection.setDoOutput(true);
        urlConnection.setRequestMethod("POST");
        urlConnection.setRequestProperty("Connection", "Keep-Alive");
        urlConnection.setRequestProperty("Cache-Control", "no-cache");
        urlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

        DataOutputStream request = new DataOutputStream(urlConnection.getOutputStream());

        request.writeBytes(twoHyphens + boundary + crlf);
        request.writeBytes("Content-Disposition: form-data; name=\"" + attachmentName + "\";filename=\"" + attachmentFileName + "\"" + crlf);
        request.writeBytes(crlf);

        int bytes = bitmap.getByteCount();
        ByteBuffer buffer = ByteBuffer.allocate(bytes);
        bitmap.copyPixelsToBuffer(buffer);
        byte[] pixels = buffer.array();

        request.write(pixels);

        request.writeBytes(crlf);
        request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);

        request.flush();
        request.close();

        InputStream responseStream = new BufferedInputStream(urlConnection.getInputStream());
        BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
        String line = "";
        StringBuilder stringBuilder = new StringBuilder();
        while ((line = responseStreamReader.readLine()) != null) {
            stringBuilder.append(line).append("\n");
        }
        responseStreamReader.close();
        String response = stringBuilder.toString();
        urlConnection.disconnect();
        return response;
    } catch (IOException exception) {
        Log.e (TAG, "HTTP Post failed", exception);
        return null;
    }
}

Thank you for your help with this!

Aaron Dougherty
  • 727
  • 6
  • 9
  • 1
    well the file is going to be compressed with png or jpeg, etc, you are sending a raw bitmap to the server. – Breavyn Sep 20 '15 at 10:15
  • I see. I've always wondered about that. If there was an implicit conversion to Bitmap going on there. I guess that means yes. In theory, though the bitmap should be visible on the server just fine though. I will, however, experiment with compressing before sending to the server and see what happens. – Aaron Dougherty Sep 20 '15 at 10:20
  • 1
    `MediaStore.Images.Media.getBitmap()` - you are converting to a bitmap. Unless the file was already a raw bitmap it will change. If you re compress it, you have to use the same compression parameters the file was created with. And in the case of a lossy format, eg jpeg, you will never get the same output. Does it matter if the file is exactly the same on the server? If it doesn't I would just use a jpeg compression to save on data. – Breavyn Sep 20 '15 at 10:25

1 Answers1

0

Many thanks to @Colin Gillespie. I compressed the data to jpeg before sending to the server, and it came out perfect on the other side. I'm still quite confused as to why my browser couldn't display the raw bitmap, but I won't look a gift-horse in the mouth.

Aaron Dougherty
  • 727
  • 6
  • 9