views:

557

answers:

5

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 of, accesssing images remotely without downloading them from the server or downloading and storing them in a Bitmap array and using them locally is a better method? 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.

+2  A: 

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.

Dylan McClung
Thank you. Any tutorials on how to send the image to the server using http client would be great.
primalpop
+2  A: 

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.

Piro
As I mentioned earlier, the images I am sending are small in size. So do I need to use MultiPartEntity to send them?
primalpop
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
The images chosen from the gallery are sent to the server after scaling it to 50*50 dip. So I don't have a path to add to list value name pairs. So only the second approach you mentioned seems possible.
primalpop
You could save the image to a temporary file or if you want to skip all this you could take a look at http://androidcodemonkey.blogspot.com/2010/03/how-to-base64-encode-decode-android.html. This describes how to use Base64 encode. You can just use that as a string and skip my MultipartEntity example.
Piro
I am sending the images using this approach only i.e Filebody but it gives OutOfMemory Exception while uploading images. Is there any way we can handle that.
sunil
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. :-(
Neil Traft
Not at the moment as far as I know. You could go with the base64 encoding and just post that as string data to your server and decode it on the backend. That way you don't need to import the .jar's.
Piro
A: 

You're Great, It worked for me after trying for 3 days everywhere else; :)

Husyn
A: 

THANKS!!! I was beating my head against the wall for DAYS! trying to fit a bit map into FileBody or something along those lines. Base64 was a perfect method for me.

Jim