Enviar imágenes usando Http Post

Deseo enviar una imagen del cliente de Android al servidor de Django utilizando Http Post. La imagen se elige de la galería. En este momento, estoy usando pares de nombre de valor de lista para enviar los datos necesarios al servidor y recibir respuestas de Django en JSON. ¿Se puede usar el mismo enfoque para las imágenes (con urls para las imágenes integradas en las respuestas de JSON)?

Además, ¿cuál es un mejor método: acceder a las imágenes de forma remota sin descargarlas del servidor o descargarlas y almacenarlas en una matriz de mapas de bits y usarlas localmente? Las imágenes son pocas (<10) y pequeñas (50 * 50 inmersiones).

Cualquier tutorial para abordar estos problemas sería muy apreciado.

Editar: las imágenes elegidas de la galería se envían al servidor después de escalarlas al tamaño requerido.

Voy a suponer que conoces la ruta y el nombre de archivo de la imagen que deseas subir. Agregue esta cadena a su NameValuePair usando image como el nombre clave.

El envío de imágenes se puede hacer utilizando las bibliotecas de HttpComponents . Descargue el último paquete binario HttpClient (actualmente 4.0.1 ) con dependencias y copie apache-mime4j-0.6.jar y httpmime-4.0.1.jar en su proyecto y agréguelos a su ruta de comstackción de Java.

Deberá agregar las siguientes importaciones a su clase.

 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; 

Ahora puede crear un MultipartEntity para adjuntar una imagen a su solicitud POST. El siguiente código muestra un ejemplo de cómo hacer esto:

 public void post(String url, List 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(); } } 

Espero que esto te ayude un poco en la dirección correcta.

Versión 4.3.5 Código actualizado

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

Dado que MultipartEntity ha quedado obsoleto . Por favor mira el código a continuación.

 String responseBody = "failure"; HttpClient client = new DefaultHttpClient(); client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); String url = WWPApi.URL_USERS; Map map = new HashMap(); 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(); } 

La biblioteca loopj se puede utilizar de forma directa para este propósito:

 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/

Luché mucho intentando implementar publicar una imagen del cliente de Android a servlet usando httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. Siempre tengo un error de tiempo de ejecución. Descubrí que, básicamente, no puedes usar estos flasks con Android, ya que Google usa una versión anterior de HttpClient en Android. La explicación está aquí http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html . Debe obtener el jarro httpclientandroidlib-1.2.1 de la biblioteca http-client de Android . A continuación, cambie sus importaciones de or.apache.http.client a ch.boye.httpclientandroidlib. Espero que esto ayude.

Normalmente hago esto en el hilo que maneja la respuesta json:

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

Si necesita hacer transformaciones en la imagen, querrá crear un Drawable en lugar de un Bitmap.