Http Post를 사용하여 이미지 전송


129

Http Post를 사용하여 안드로이드 클라이언트에서 Django 서버로 이미지를 보내고 싶습니다. 이미지는 갤러리에서 선택됩니다. 현재 목록 값 이름 쌍을 사용하여 필요한 데이터를 서버로 보내고 JSON의 Django에서 응답을받습니다. 이미지에 동일한 접근 방식을 사용할 수 있습니까 (JSON 응답에 포함 된 이미지의 URL 포함)?

또한 서버에서 이미지를 다운로드하지 않고 원격으로 이미지를 액세스하거나 비트 맵 배열로 이미지를 다운로드하여 저장 한 후 로컬로 사용하는 것이 더 좋은 방법입니다. 이미지 수는 적고 (<10) 크기는 작습니다 (50 * 50 딥).

이러한 문제를 해결하기위한 튜토리얼은 대단히 감사하겠습니다.

편집 : 갤러리에서 선택한 이미지가 필요한 크기로 조정 된 후 서버로 전송됩니다.

답변:


144

업로드하려는 이미지의 경로와 파일 이름을 알고 있다고 가정하겠습니다. 키 이름으로 NameValuePair사용 하여이 문자열을 추가하십시오 image.

이미지 전송은 HttpComponents 라이브러리를 사용하여 수행 할 수 있습니다 . 최신 HttpClient를 (현재 다운로드 4.0.1 의존성 패키지) 바이너리를 복사 apache-mime4j-0.6.jar하고 httpmime-4.0.1.jar프로젝트와 자바 빌드 경로에 추가합니다.

수업에 다음 수입품을 추가해야합니다.

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;

이제 MultipartEntityPOST 요청에 이미지를 첨부 할 수 있습니다 . 다음 코드는이를 수행하는 방법의 예를 보여줍니다.

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 인코딩 문자열로 인코딩하고 서버 측에서 디코딩하는 것입니다. 그러나 이것은 내 의견으로는 너무 번거롭고 갈 길은 아닙니다.
Piro

6
안녕하세요, MultipartEntity 없이이 작업을 수행 할 수있는 방법이 있습니까? 나는 그 4 가지 클래스에 대해서만 모든 Apache HC를 가져오고 싶지 않다. :-(
Neil Traft

6
FileBody원하는 Mime 유형 으로 두 번째 매개 변수를 추가 하십시오. 예 :new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")
Piro

4
다중 파티션이 더 이상 사용되지 않는 것 같습니다.
Nanne

1
@ Piro 나는 당신의 답변을 편집하려고 생각했습니다. 멀티 파트 엔티티는 사용중인 문자열 본문 버전과 함께 감가 상각됩니다. 내가 편집하지 않는 이유는 당신이 한 것처럼 이름 값 쌍의 모든 데이터를 바인딩 할 수 없기 때문입니다.
불법 인수

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

어떤 jar 패키지가 필요합니까?

3
httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar
AZ_

addQueryParams는 무엇을 반환합니까?
San

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

httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar을 사용하여 Android 클라이언트에서 서블릿으로 이미지를 게시하려고 많은 노력을 기울였습니다. 항상 런타임 오류가 발생했습니다. Google이 Android에서 이전 버전의 HttpClient를 사용하고 있기 때문에 기본적으로 Android에서 이러한 항아리를 사용할 수 없다는 것을 알았습니다. 설명은 여기 http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html 입니다. Android http-client 라이브러리 에서 httpclientandroidlib-1.2.1 jar을 가져와야 합니다. . 그런 다음 가져 오기를 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();
}

이미지를 변형해야하는 경우 비트 맵 대신 드로어 블을 만들어야합니다.


3
문제는 이미지를 게시하는 방법이 아니라 이미지를 게시하는 방법입니다.
dwbrito
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.