以字节数组上传到服务器的映像损坏(无法打开图像)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以字节数组上传到服务器的映像损坏(无法打开图像)相关的知识,希望对你有一定的参考价值。

服务器端期望图像以字节数组发送,我能够成功上传图像(200响应)但是当服务器图像中的检查图像被破坏时(图像无法打开)。

我尝试了以下方式上传图片(字节数组)。

第一路

HttpClient httpclient = new DefaultHttpClient();

HttpPost httppost = new HttpPost(url);
httppost.addHeader("Content-Type", "multipart/form-data");

try {
    androidMultiPartEntity entity = new AndroidMultiPartEntity(
            new AndroidMultiPartEntity.ProgressListener() {

                @Override
                public void transferred(long num) {

                    publishProgress((int) ((num / (float) totalSize) * 100));
                }
            });

    File sourceFile = new File("filepath");

    // Adding file data to http body
    entity.addPart("image", new FileBody(sourceFile));

    totalSize = entity.getContentLength();
    httppost.setEntity(entity);

    // Making server call
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity r_entity = response.getEntity();

第二种方式

HttpPost httppost = new HttpPost(url);

try {
    AndroidMultiPartEntity entity = new AndroidMultiPartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
            new AndroidMultiPartEntity.ProgressListener() {

                @Override
                public void transferred(long num) {

                    publishProgress((int) ((num / (float) totalSize) * 100));
                }
            });

    File sourceFile = new File("filepath");
    FileInputStream fis = new FileInputStream(sourceFile);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[1024];
    try {
        for (int readNum; (readNum = fis.read(buf)) != -1;) {
            bos.write(buf, 0, readNum); //no doubt here is 0
            //Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
            System.out.println("read " + readNum + " bytes,");
        }
    } catch (IOException ex) {

    }

    httppost.addHeader("Content-Type", "multipart/form-data");
    httppost.setEntity(new ByteArrayEntity(buf));
     // Making server call
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity r_entity = response.getEntity();

在这两种情况下,图像上传后会上传后损坏(不可见)。

有人能让我知道我做错了什么吗?如何将字节数组中的图像上传到服务器而不会导致图像损坏?

答案

这是我使用的示例上传图像功能,这是有效的。但是,我已经使用Volley实现了图像上传。您可能需要对功能进行一些更改才能使其适用于您的情况。

public static void uploadImage(final Context context, final String filePath) {
    VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, postUrl, new Response.Listener<NetworkResponse>() {
        @Override
        public void onResponse(NetworkResponse response) {
            String resultResponse = new String(response.data);
            try {
                JSONObject result = new JSONObject(resultResponse);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            NetworkResponse networkResponse = error.networkResponse;
            String errorMessage = "Unknown error";
            if (networkResponse == null) {
                if (error.getClass().equals(TimeoutError.class)) {
                    errorMessage = "Request timeout";
                } else if (error.getClass().equals(NoConnectionError.class)) {
                    errorMessage = "Failed to connect server";
                }
            } else {
                String result = new String(networkResponse.data);
                try {
                    JSONObject response = new JSONObject(result);
                    String status = response.getString("status");
                    String message = response.getString("message");

                    Log.e("Error Status", status);
                    Log.e("Error Message", message);

                    if (networkResponse.statusCode == 404) {
                        errorMessage = "Resource not found";
                    } else if (networkResponse.statusCode == 401) {
                        errorMessage = message + " Please login again";
                    } else if (networkResponse.statusCode == 400) {
                        errorMessage = message + " Check your inputs";
                    } else if (networkResponse.statusCode == 500) {
                        errorMessage = message + " Something is getting wrong";
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Log.i("Error", errorMessage);
            error.printStackTrace();
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            return params;
        }

        @Override
        protected Map<String, DataPart> getByteData() {
            Map<String, DataPart> params = new HashMap<>();
            // file name could found file base or direct access from real path
            // for now just get bitmap data from ImageView
            params.put("template", new DataPart("profile_picture",
                    readImageFile(filePath)));
            return params;
        }
    };

    VolleySingleton.getInstance(context).addToRequestQueue(multipartRequest);
}

public static byte[] readImageFile(String fileName) {
    File root = android.os.Environment.getExternalStorageDirectory();
    File dir = new File(root.getAbsolutePath() + IMAGE_DIRECTORY);
    File file = new File(dir, fileName);

    int size = (int) file.length();
    byte[] bytes = new byte[size];
    try {
        BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
        buf.read(bytes, 0, bytes.length);
        buf.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }

    return bytes;
}

要使用Volley,您需要在build.gradle文件中添加以下依赖项。

dependencies {
    // ... Other dependencies
    compile 'com.android.volley:volley:1.0.0'
}

以上是关于以字节数组上传到服务器的映像损坏(无法打开图像)的主要内容,如果未能解决你的问题,请参考以下文章

使用 servlet 上传后图像文件已损坏 [重复]

FTPClient 在上传到 android 上的 ftp 服务器时损坏图像?

如何以BLOB格式将图像上传到Firebase存储?

Android:上传到服务器的图像始终为 0 字节

在网站加载但未正确加载的图像(已损坏)

使用 AFNetworking 上传后图像不显示在浏览器上