Надсилання зображень за допомогою Http Post


129

Я хочу надіслати зображення з Android-клієнта на сервер Django за допомогою Http Post. Зображення вибирається з галереї. В даний час я використовую ім'я списку значень «Пара» для надсилання необхідних даних на сервер та отримання відповідей від Django в JSON. Чи можна використовувати такий самий підхід до зображень (з URL-адресами для зображень, вбудованих у відповіді JSON)?

Також, який кращий метод: отримати доступ до зображень віддалено, не завантажуючи їх із сервера чи завантажуючи та зберігаючи їх у масиві Bitmap та використовуючи їх локально? Зображення мало за кількістю (<10) та невеликими розмірами (50 * 50 крапель).

Буде дуже вдячний будь-який підручник для вирішення цих проблем.

Редагувати: зображення, вибрані з галереї, надсилаються на сервер після їх масштабування до потрібного розміру.

Відповіді:


144

Я припускаю, що ви знаєте шлях та назву файлу зображення, яке ви хочете завантажити. Додайте цей рядок до свого NameValuePairвикористання imageяк імені ключа.

Надсилання зображень можна здійснити за допомогою бібліотеки HttpComponents . Завантажте останню HttpClient ( в даний час 4.0.1 ) двійковий файл з пакетом залежностей і скопіювати apache-mime4j-0.6.jarі httpmime-4.0.1.jarв свій проект і додати їх в свій шлях збірки Java.

Вам потрібно буде додати наступний імпорт до свого класу.

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;

Тепер ви можете створити, MultipartEntityщоб прикріпити зображення до вашого POST-запиту. Наступний код показує приклад того, як це зробити:

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

Я сподіваюся, що це допоможе вам трохи в правильному напрямку.


6
Я б напевно рекомендував це. Таким чином, ви, ймовірно, можете використовувати функції Django для отримання зображення та його легко зберігати. Ще одним способом було б кодування потоку байтів із зображення в кодовану рядок base64 та декодування його на стороні сервера. Але це було б занадто великим клопотом на мою думку, а не дорогою.
Піро

6
Ей, хлопці, чи можна це зробити без MultipartEntity? Я дійсно не хочу імпортувати весь Apache HC тільки для цих 4 класів. :-(
Ніл Трафт

6
Просто додайте другий параметр до FileBodyпотрібного типу Mime. Напр .:new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")
Піро

4
Схоже, що багатопаритетність застаріла?
Нанна

1
@Piro Я теж думав над редагуванням вашої відповіді. Багаточастинне об'єднання амортизується разом із версією корпусу рядка, яку ви використовуєте. Причина, яку я не редагую, полягає в тому, що я не міг прив’язати всі дані до namevaluepairs, як ви це зробили.
Незаконний аргумент

15

Версія 4.3.5 оновлений код

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

З MultipartEntityмоменту застарілості . Будь ласка, дивіться код нижче.

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
httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar
AZ_

Що повертає addQueryParams?
Сан-

11

Для цього бібліотеку loopj можна використовувати прямо:

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/


5

Я багато намагався реалізувати розміщення зображення з клієнта Android на сервлеті за допомогою httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. У мене завжди була помилка виконання. Я з’ясував, що в основному ви не можете використовувати ці банки з Android, оскільки Google використовує старішу версію HttpClient в Android. Пояснення тут http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html . Вам потрібно отримати банку httpclientandroidlib-1.2.1 з бібліотеки андроїд http-клієнт . Потім змініть імпорт з or.apache.http.client на ch.boye.httpclientandroidlib. Сподіваюся, це допомагає.


-13

Зазвичай я це роблю в потоці, що обробляє відповідь json:

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

Якщо вам потрібно зробити перетворення на зображенні, вам потрібно створити Dravable замість растрової карти.


3
Питання в тому, як розмістити зображення, а не як його отримати.
dwbrito
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.