Sending images using Http Post

AndroidDjangoHttp

Android Problem Overview


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.

Android Solutions


Solution 1 - Android

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][1]. Download the latest HttpClient (currently [4.0.1][2]) 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.

[1]: http://hc.apache.org/downloads.cgi "HttpComponents library" [2]: http://apache.cs.uu.nl/dist/httpcomponents/httpclient/binary/httpcomponents-client-4.0.1-bin-with-dependencies.zip "HttpClient 4.0.1 - Binary with dependencies"

Solution 2 - Android

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

Solution 3 - Android

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/

Solution 4 - Android

I struggled a lot trying to implement posting a image from Android client to servlet using httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. I always got a runtime error. I found out that basically you cannot use these jars with Android as Google is using older version of HttpClient in Android. The explanation is here http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html. You need to get the httpclientandroidlib-1.2.1 jar from android http-client library. Then change your imports from or.apache.http.client to ch.boye.httpclientandroidlib. Hope this helps.

Solution 5 - Android

I usually do this in the thread handling the json response:

try {
  Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
} catch (MalformedURLException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

If you need to do transformations on the image, you'll want to create a Drawable instead of a Bitmap.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPrimal PappachanView Question on Stackoverflow
Solution 1 - AndroidPiroView Answer on Stackoverflow
Solution 2 - AndroidAZ_View Answer on Stackoverflow
Solution 3 - Androidvonox7View Answer on Stackoverflow
Solution 4 - AndroidDavidCView Answer on Stackoverflow
Solution 5 - AndroidDylan McClungView Answer on Stackoverflow