Categories
android django http

Sending images using Http Post

132

I want to send an image from the android client to the Django server using Http Post. The image is chosen from the gallery. At present, I am using list value name Pairs to send the necessary data to the server and receiving responses from Django in JSON. Can the same approach be used for images (with urls for images embedded in JSON responses)?

Also, which is a better method: accessing images remotely without downloading them from the server or downloading and storing them in a Bitmap array and using them locally? The images are few in number (<10) and small in size (50*50 dip).

Any tutorial to tackle these problems would be much appreciated.

Edit: The images chosen from the gallery are sent to the server after scaling it to required size.

0

    146

    I’m going to assume that you know the path and filename of the image that you want to upload. Add this string to your NameValuePair using image as the key-name.

    Sending images can be done using the HttpComponents libraries. Download the latest HttpClient (currently 4.0.1) binary with dependencies package and copy apache-mime4j-0.6.jar and httpmime-4.0.1.jar to your project and add them to your Java build path.

    You will need to add the following imports to your class.

    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntity;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.entity.mime.content.StringBody;
    

    Now you can create a MultipartEntity to attach an image to your POST request. The following code shows an example of how to do this:

    public void post(String url, List<NameValuePair> nameValuePairs) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);
    
        try {
            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    
            for(int index=0; index < nameValuePairs.size(); index++) {
                if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) {
                    // If the key equals to "image", we use FileBody to transfer the data
                    entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File (nameValuePairs.get(index).getValue())));
                } else {
                    // Normal string data
                    entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue()));
                }
            }
    
            httpPost.setEntity(entity);
    
            HttpResponse response = httpClient.execute(httpPost, localContext);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    I hope this helps you a bit in the right direction.

    19

    • 6

      I would most definitely recommend this. This way you probably can use Django features to receive the image and store it easily. One other way would be to encode the byte stream from the image to a base64 encoded string and decode it server side. But this would be too much of a hassle in my opinion and not the way to go.

      – Piro

      May 30, 2010 at 1:16


    • 6

      Hey guys, is there any way to do this without MultipartEntity? I REALLY don’t want to import all of Apache HC just for those 4 classes. 🙁

      Aug 1, 2010 at 15:53

    • 6

      Just add a 2nd parameter to FileBody with your desired Mime Type. E.g.: new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")

      – Piro

      Mar 8, 2011 at 22:25


    • 4

      It looks like multipartentity is deprecated?

      – Nanne

      Jan 5, 2014 at 10:18

    • 1

      @Piro I was thinking about editing your answer too. Multipart entity is depreciated along with the string body version that you are using. The reason I am not editing is because i couldnot bind all data in namevaluepairs as you have done.

      Feb 25, 2014 at 7:42

    15

    Version 4.3.5 Updated Code

    • httpclient-4.3.5.jar
    • httpcore-4.3.2.jar
    • httpmime-4.3.5.jar

    Since MultipartEntity has been deprecated. Please see the code below.

    String responseBody = "failure";
    HttpClient client = new DefaultHttpClient();
    client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    
    String url = WWPApi.URL_USERS;
    Map<String, String> map = new HashMap<String, String>();
    map.put("user_id", String.valueOf(userId));
    map.put("action", "update");
    url = addQueryParams(map, url);
    
    HttpPost post = new HttpPost(url);
    post.addHeader("Accept", "application/json");
    
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.setCharset(MIME.UTF8_CHARSET);
    
    if (career != null)
        builder.addTextBody("career", career, ContentType.create("text/plain", MIME.UTF8_CHARSET));
    if (gender != null)
        builder.addTextBody("gender", gender, ContentType.create("text/plain", MIME.UTF8_CHARSET));
    if (username != null)
        builder.addTextBody("username", username, ContentType.create("text/plain", MIME.UTF8_CHARSET));
    if (email != null)
        builder.addTextBody("email", email, ContentType.create("text/plain", MIME.UTF8_CHARSET));
    if (password != null)
        builder.addTextBody("password", password, ContentType.create("text/plain", MIME.UTF8_CHARSET));
    if (country != null)
        builder.addTextBody("country", country, ContentType.create("text/plain", MIME.UTF8_CHARSET));
    if (file != null)
        builder.addBinaryBody("Filedata", file, ContentType.MULTIPART_FORM_DATA, file.getName());
    
    post.setEntity(builder.build());
    
    try {
        responseBody = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8");
    //  System.out.println("Response from Server ==> " + responseBody);
    
        JSONObject object = new JSONObject(responseBody);
        Boolean success = object.optBoolean("success");
        String message = object.optString("error");
    
        if (!success) {
            responseBody = message;
        } else {
            responseBody = "success";
        }
    
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        client.getConnectionManager().shutdown();
    }
    

    3

    • Which jar packages is needed?

      – user679937

      Sep 11, 2014 at 4:55

    • 3

      httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar

      – AZ_

      Sep 11, 2014 at 6:05

    • What does addQueryParams return ?

      – San

      Oct 21, 2015 at 6:40

    11

    The loopj library can be used straight-forward for this purpose:

    SyncHttpClient client = new SyncHttpClient();
    RequestParams params = new RequestParams();
    params.put("text", "some string");
    params.put("image", new File(imagePath));
    
    client.post("http://example.com", params, new TextHttpResponseHandler() {
      @Override
      public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
        // error handling
      }
    
      @Override
      public void onSuccess(int statusCode, Header[] headers, String responseString) {
        // success
      }
    });
    

    http://loopj.com/

    0