1

I have two images, saved as Bitmaps in memory:

private Bitmap image1;
private Bitmap image2;

Now I want to upload these Bitmaps to my server. Here is what I do at the moment: I write my images to the file system (e.g. internal storage) as PNG, using URI for the location. Then I call this method to upload the files using multipart POST:

private int uploadImageFiles(String image1Uri, String image2Uri) {
    File image1 = new File(image1Uri);
    File image2 = new File(image2Uri);

    try {
         HttpClient client = new DefaultHttpClient();
         HttpPost post = new HttpPost(uploadServerUriNodeJs);

         // additional headers for node.js server
         post.addHeader("ACCEPT", "application/melancholia+json");
         post.addHeader("ACCEPT-VERSION", "1.0");

         // user authorization
         String usernamePassword = USER + ":" + PASSWORD;
         String encodedUsernamePassword = Base64.encodeToString(usernamePassword.getBytes(), Base64.NO_WRAP);
         post.addHeader("AUTHORIZATION", "Basic " + encodedUsernamePassword);

         FileBody bin1 = new FileBody(image1, "image/png");
         FileBody bin2 = new FileBody(image2, "image/png");
         MultipartEntity reqEntity = new MultipartEntity();
         reqEntity.addPart("image1", bin1);
         reqEntity.addPart("image2", bin2);
         post.setEntity(reqEntity);
         HttpResponse response = client.execute(post);
         HttpEntity resEntity = response.getEntity();
         final String response_str = EntityUtils.toString(resEntity);
         if (resEntity != null) {
             return getIdFromResponse(response_str);
         }
    }
    catch (Exception ex){
         Log.e("Debug", "error: " + ex.getMessage(), ex);
    }
    return -1;
}

Now my problem: I do not need to write these Bitmaps to the file system for my application - except for the Upload. Image files can be quite large in size, so it can take some considerable additional time to write them to the file system first, which is bad for performance.

What I want: Is there a way to upload my Bitmaps without saving them to the file system first?

I am not allowed to make changes to the server, by the way.


UPDATE: Here is how I solved it:

this sample is using apache httpclient 4.3.6 get it at http://hc.apache.org/downloads.cgi and see this post to know what libraries to include: Upload Photo using HttpPost MultiPartEntityBuilder also do not forget to check them at tab "order and export"

private String uploadImagesFromMemory(Bitmap img1, Bitmap img2) {

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    img1.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] bin1 = stream.toByteArray();

    ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
    img2.compress(Bitmap.CompressFormat.PNG, 100, stream2);
    byte[] bin2 = stream2.toByteArray();

    try {
     HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(uploadServerUriNodeJs);

        // additional headers for node.js server
        post.addHeader("ACCEPT", "application/melancholia+json");
        post.addHeader("ACCEPT-VERSION", "1.0");

        // user authorization
        String usernamePassword = USER + ":" + PASSWORD;
        String encodedUsernamePassword = Base64.encodeToString(usernamePassword.getBytes(), Base64.NO_WRAP);
        post.addHeader("AUTHORIZATION", "Basic " + encodedUsernamePassword);

        HttpEntity reqEntity = MultipartEntityBuilder.create()
                .addBinaryBody("img1", bin1, ContentType.create("image/png"), "img1.png")
                .addBinaryBody("img2", bin2, ContentType.create("image/png"), "img2.png")
                .build();

        post.setEntity(reqEntity);
        Log.i("REQUEST", post.getRequestLine().toString());
        HttpResponse response = client.execute(post);
        HttpEntity resEntity = response.getEntity();
        final String response_str = EntityUtils.toString(resEntity);
        if (resEntity != null) {
            a.runOnUiThread(new Runnable(){
                   public void run() {
                        try {
                           Log.i("RESPONSE", "Response from server : " + response_str);
                       } catch (Exception e) {
                           e.printStackTrace();
                       }
                      }
               });
            return response_str;
        }
   }
   catch (Exception ex){
        Log.e("Debug", "error: " + ex.getMessage(), ex);
   }
   return "";
}
Community
  • 1
  • 1
crazy
  • 57
  • 1
  • 11

2 Answers2

1

Yes, you can upload bitmaps without saving them to the file system. Write to OutputStream returned by HttpURLConnection.

private Bitmap bitmap;
HttpURLConnection connection;

    try
    {
        URL url = new URL("urlServer");
        connection = (HttpURLConnection) url.openConnection();

        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type", "multipart/form-data;");

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        OutputStream outputStream = connection.getOutputStream();
        outputStream.write(byteArray);
        outputStream.flush();
        outputStream.close();
    }
    catch (Exception ex)
    {
        //Exception handling
    }
    finally {
        if(connection != null) {
            connection.disconnect();
        }
    }
michal.z
  • 2,025
  • 1
  • 15
  • 10
  • thank you, but please have a look at my comment above: http://stackoverflow.com/a/27369501/3991799 – crazy Dec 09 '14 at 00:44
0

verify that the server will accept a plain POST ( not mime multipart )

curl -X POST "https://youserver/path --header "Transfer-Encoding: chunked" --header "Content-Type: pic/*;"  --data-binary @Your-photo

Play around with presence absence of the header ( your server may be very dependent on specific MIME types for this kind of POST )

If it works , then you can do diff type of upload from android using POST with 'byteArrayEntity' as the post body.

Get a Stream from the bitmap's ByteArray and feed it to the input Stream in this example

Robert Rowntree
  • 6,230
  • 2
  • 24
  • 43
  • well, the server is a node.js server with currently very limited funtionality. a plain post probably will not work. I already tried different solutions for uploading and needed hours to get it working. is there not any solution where I could just create some kind of "fake file" or "fake filebody" from my bitmap and use my method written above? – crazy Dec 09 '14 at 00:42