Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have an app that will be sending images ranging from few KB to ~20MB and I need to write a code that will do that in the fastest and most efficient way. I currently have a code that does this, but I fear that it's inefficient and slow:

// Read bitmap from file
Bitmap bitmap = null;
Uri uri = Uri.fromFile(new File("camera/myfile.jpg"));
InputStream stream = null;

try {
    stream = getContentResolver().openInputStream(uri);
    BitmapFactory.Options options = new BitmapFactory.Options();
    bitmap = BitmapFactory.decodeStream(stream, null, options);
} catch (IOException e) {
    Log.e(TAG, e.getMessage(),e);
    return null;
} finally {
    try {
        if (stream != null) stream.close();
    } catch (Exception e) {}
}

// Send image data to server
ByteArrayOutputStream byteStream = null;

try {
    // Create HTTP objects
    DefaultHttpClient httpClient = new DefaultHttpClient();
    BasicHttpParams hparams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(hparams,10*1000);
    httpClient.setParams(hparams);
    HttpPost httpPost = new HttpPost(my_servers_url);

    byteStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream);

    // Convert ByteArrayOutputStream to byte array. Close stream.
    byte[] byteArray = byteStream.toByteArray();
    byteStream.close();
    byteStream = null;

    // Send HTTP Post request
    httpPost.setEntity(new ByteArrayEntity(byteArray));
    String response = EntityUtils.toString(httpClient.execute(httpPost).getEntity(), HTTP.UTF_8);

} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (byteStream != null) byteStream.close();
    } catch (Exception e) {}
}

My concern is that the entirety of the image is loaded into a byte array on the device before being sent to the server. Although this code works, it is slower than what I'm satisfied with.

Can this code be faster and more efficient? Would it be better to use HttpURLConnection instead? If so, how would I write the code?

share|improve this question

migrated from stackoverflow.com Jun 27 at 14:15

This question came from our site for professional and enthusiast programmers.

    
I don't understand why you decode the JPEG file to a bitmap and then compress it to JPEG. Is this important or could you just send the JPEG from the camera "raw" to your server? If the latter is the case, then I could help you to do implement it more efficiently with HttpURLConnection. –  hgoebl Jun 25 at 16:17
    
@hgoebl Sure, could you show me how with HttpUrlConnection? –  baekacaek Jun 25 at 20:39
    
I certainly hope you are not running this in the main thread. –  toto2 Jun 27 at 19:58
    
I would not worry about taking 20MB of memory. Most devices have 1GB and over. –  toto2 Jun 27 at 19:59
add comment

1 Answer

I've implemented a tiny wrapper around HttpURLConnection called DavidWebb. You can set the body as File or InputStream and it will stream the content to the server:

Webb webb = Webb.create();
Response<String> response = webb
        .post("http://www.example.com/service")
        .body(new File("camera/myfile.jpg"))
        .connectTimeout(10 * 1000)
        .asString();

if (response.isSuccess()) {
    String outcome = response.getBody();

    // ...

} else {
    System.out.println(response.getStatusCode());
    System.out.println(response.getResponseMessage());
    System.out.println(response.getErrorBody());
}

If you don't give a File object, but an InputStream, you have to take care closing the stream.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.