Android:上传位图而不先将它们保存到文件系统

时间:2014-12-09 00:00:42

标签: android bitmap upload

我有两张图片,在内存中保存为位图:

private Bitmap image1;
private Bitmap image2;

现在我想将这些位图上传到我的服务器。这就是我现在所做的事情: 我将图像作为PNG写入文件系统(例如内部存储器),使用URI作为位置。然后我调用此方法使用多部分POST上传文件:

private int uploadImageFiles(String image1Uri, String image2Uri) {
    File image1 = new File(image1Uri);
    File image2 = new File(image2Uri);

    try {
         HttpClient client = new DefaultHttpClient();
         HttpPost post = new HttpPost(uploadServerUriNodeJs);

         // additional headers for node.js server
         post.addHeader("ACCEPT", "application/melancholia+json");
         post.addHeader("ACCEPT-VERSION", "1.0");

         // user authorization
         String usernamePassword = USER + ":" + PASSWORD;
         String encodedUsernamePassword = Base64.encodeToString(usernamePassword.getBytes(), Base64.NO_WRAP);
         post.addHeader("AUTHORIZATION", "Basic " + encodedUsernamePassword);

         FileBody bin1 = new FileBody(image1, "image/png");
         FileBody bin2 = new FileBody(image2, "image/png");
         MultipartEntity reqEntity = new MultipartEntity();
         reqEntity.addPart("image1", bin1);
         reqEntity.addPart("image2", bin2);
         post.setEntity(reqEntity);
         HttpResponse response = client.execute(post);
         HttpEntity resEntity = response.getEntity();
         final String response_str = EntityUtils.toString(resEntity);
         if (resEntity != null) {
             return getIdFromResponse(response_str);
         }
    }
    catch (Exception ex){
         Log.e("Debug", "error: " + ex.getMessage(), ex);
    }
    return -1;
}

现在我的问题:我不需要将这些位图写入我的应用程序的文件系统 - 除了上传。图像文件的大小可能非常大,因此首先将它们写入文件系统需要相当长的时间,这对性能不利。

我想要的是:有没有办法上传我的位图而不先将它们保存到文件系统?

顺便说一下,我不允许对服务器进行更改。


更新:我的解决方法如下:

此示例使用的是apache httpclient 4.3.6 在http://hc.apache.org/downloads.cgi获取 并查看此帖子以了解要包含的库:Upload Photo using HttpPost MultiPartEntityBuilder 也不要忘记在选项卡"订购并导出"

private String uploadImagesFromMemory(Bitmap img1, Bitmap img2) {

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    img1.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] bin1 = stream.toByteArray();

    ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
    img2.compress(Bitmap.CompressFormat.PNG, 100, stream2);
    byte[] bin2 = stream2.toByteArray();

    try {
     HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(uploadServerUriNodeJs);

        // additional headers for node.js server
        post.addHeader("ACCEPT", "application/melancholia+json");
        post.addHeader("ACCEPT-VERSION", "1.0");

        // user authorization
        String usernamePassword = USER + ":" + PASSWORD;
        String encodedUsernamePassword = Base64.encodeToString(usernamePassword.getBytes(), Base64.NO_WRAP);
        post.addHeader("AUTHORIZATION", "Basic " + encodedUsernamePassword);

        HttpEntity reqEntity = MultipartEntityBuilder.create()
                .addBinaryBody("img1", bin1, ContentType.create("image/png"), "img1.png")
                .addBinaryBody("img2", bin2, ContentType.create("image/png"), "img2.png")
                .build();

        post.setEntity(reqEntity);
        Log.i("REQUEST", post.getRequestLine().toString());
        HttpResponse response = client.execute(post);
        HttpEntity resEntity = response.getEntity();
        final String response_str = EntityUtils.toString(resEntity);
        if (resEntity != null) {
            a.runOnUiThread(new Runnable(){
                   public void run() {
                        try {
                           Log.i("RESPONSE", "Response from server : " + response_str);
                       } catch (Exception e) {
                           e.printStackTrace();
                       }
                      }
               });
            return response_str;
        }
   }
   catch (Exception ex){
        Log.e("Debug", "error: " + ex.getMessage(), ex);
   }
   return "";
}

2 个答案:

答案 0 :(得分:1)

是的,您可以上传位图而不将其保存到文件系统。写信至OutputStream返回的HttpURLConnection

private Bitmap bitmap;
HttpURLConnection connection;

    try
    {
        URL url = new URL("urlServer");
        connection = (HttpURLConnection) url.openConnection();

        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type", "multipart/form-data;");

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        OutputStream outputStream = connection.getOutputStream();
        outputStream.write(byteArray);
        outputStream.flush();
        outputStream.close();
    }
    catch (Exception ex)
    {
        //Exception handling
    }
    finally {
        if(connection != null) {
            connection.disconnect();
        }
    }

答案 1 :(得分:0)

验证服务器是否接受普通POST(不是mime multipart)

curl -X POST "https://youserver/path --header "Transfer-Encoding: chunked" --header "Content-Type: pic/*;"  --data-binary @Your-photo

在没有标题的情况下玩游戏(您的服务器可能非常依赖于此类POST的特定MIME类型)

如果它有效,那么你可以使用POST以'byteArrayEntity'作为帖子正文从android进行diff类型的上传。

从位图的ByteArray中获取一个Stream并将其提供给this example

中的输入流