【问题标题】:Getting a broken image string when converting gallery photo to BASE64 with Base64.EncodeString [Android] [Java]使用 Base64.EncodeString [Android] [Java] 将图库照片转换为 BASE64 时获取损坏的图像字符串
【发布时间】:2019-04-04 10:11:47
【问题描述】:

当使用 Base64 编码器从活动转换画廊照片时,我得到一个错误的 Base64 字符串。当使用一个站点来测试它时,它是一个损坏的图像。尝试发布此字符串时,我的 ExpressAPI 也会在字符串上给我一个验证错误。

我已经尝试过使用不同的位图变体,例如工厂等。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //call super
        super.onActivityResult(requestCode, resultCode, data);
        Uri imageUri = data.getData();
        InputStream imageStream = null;
        try {
            imageStream = getContentResolver().openInputStream(imageUri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
        encodedString = encodeImage(selectedImage);
    }
 private String encodeImage(Bitmap bm)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
        byte[] b = baos.toByteArray();
        String encImage = Base64.encodeToString(b, Base64.DEFAULT);
        Log.d(encImage, "Image:");
        return encImage;

    }

我显然期望一个 Base64 字符串,但相反,我得到了这个:

/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB: AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAONA1wDASIA
AhEBAxEB/8QAHwAAAQQDAQEBAQAAAAAAAAAAAAQFBgcICQoBAgML/8QAhRAAAAEHBwgGBQYHBg4M
CQEZAQACAwQFESEGBzFBUWHwCBRxgZGhscEJEhMk0eEKFSM08Ro5UpKXuBYiM0RXctgXMkNUgtIY
GSU4OkJid3iIorK3wjZWWFlkaHOVlrTU4iY1dHV2ttXW1ygqN1VmlJintbPyJ0VGR0hTZXmFhoeo
xMbH/8QAGwEBAAMBAQEBAAAAAAAAAAAAAAQFBgEDAgf/xABIEQACAAIGBwYEBQMDAgUEAwEAAQQR
ITFBUWGRAhRxgaHB8BKCorHR4QWS0vEiMkJSYgMGchWywhY1JDRUVfIjJUXiE0NTc//aAAwDAQAC EQMRAD8A7+CCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCAC
CCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACC
CCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCC
CACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCC
ACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCA
CCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCAC
CCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACC
CCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCC
CACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCC
ACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCA
CCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCAC
CCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACC
CCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCC
CACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCCACCCC
ACCCCACCCCACCCCACCCCACCCCACCCCACCCCAqOdOdGSEzM2s4M7U4zTMk3Iia6R0opwpYtmHVZcn
pKMMZSyjSC+IgahRif1QcCURE3rGiACGlHoTZZZSuVlJmfPpD8oSXcvEEm8qCcBuIMnDJ7aEo22M
30zUykm0hyJSFEr9QxFnDTWgWRzgQRowSIEyI0wEicEiDHz0oGe2VTIyUZl8jWbYw0ZysuOe+T82
Cv1DRHsVcTkYpTzjniBpqZOcgRR6oPQInCInR6JJiZoJJ5PczE1cyUi1XM5KTTyDk3N2wDRF4gxp
MsBCqoBChxoig6wgLxA4BiQHOj0C2XjlZ5YWUt0l0jcoidhBOJJqYecWT7CmpVEUjGBJ05kKq1Ku
e9CsmmirAaIiKJnqRhoHQAxUQIjjzEBhxpdS5cWvotP9eB0yf99aQ/8ApGyhC7SiAC5aMrPLpytZ
ufSDsjrIrkVO0mY+TlOvNoxGrLiboJHyCaqVrJUqCfQ1IBq4kNFeQGH+r1E0T3GpgBUVjzkfaoEf
V6ly4tMuv+ywOj5/vUTV/wCZlAkBsU6WCfmfHo7cqzI9y91acacJfyJW3KX+h3yxJqPwpTNGbSSC
vLDtBkhPOdJo/roxW1cOuiSnIj+1NAxEkSI0Ip3H9CrOaTMbCgptJlrKqvMpdUQaCivKR5nqpfMP
e494dYBNeBpwPOH8V4iLzRNDC/pKsl9Wyx8hDKbycczNWmvOBNa3fwOMMcIfh3JnqSum0OeIxdLS
TcmxOvoB7gHXF6OJlVpcqPo0ZtFOVp+dS5ye262snyVCQAA0T0jOSKQIDj4PPOSIkqM0DxERFCgM
AIOcAwqOUBl2ndPm1cnJInnBN6PtTmbMauaDNmxDZuQlMM0Zq8agCWZsmgWOp60A1yoC/wBicc5V
ihEDCXdOBlF9IBk/SkyHgyGEsv8ANJwp4mux58jZBzQMOdA46TJgSW7I9YRJzAEw8Tki2jEwOuJ5
vUE9Mf1RRGZYq3SnyDX+lJafRbmzXy0Nl+oTchLgJ1gW2F6j7D8Gvwq7EFYRBKBwIPZmmAaaIJfx
83f7EvnpKulNkF0bDVyamPLebCWU5I5S84zWm0YAyTaLBZQyaTGIUKXrnnphEUgOOR9UTRE4BMER
S9oImogNuBBBBAc2XpI2WplP5CeSXMnONkpzkmTZy1lTPwxpFNNtpZIsCUINNhpJv5VrAmmmLIJD
EZoJkSFIaBhgGGnIzAMNNNRI39EEllpYWpNMBbWwAF1ZYLEXVwa/x0BiU5wWu6z6AgNYw5R/TB/6
wrJu/wALtif6E51yzJylemwZU0k4yvklZGOS1O3l75UMgWUxwl1JCZVE2zpEzagKMDHSrlQlQpgO
ADDRNABDqj1gNSCKM3qkB0OEFyTt70ifKQyYpQsJB0ivRWT6ZMk3zfXhZRk6DHlYjlArI0gB+IlS
IwRIUqU0DnHHIwXTX0B2cBDptmYnfmyygZq5FTxzOyqY0uZsZwZOMeUUjJWM4esx2qwzhDqHmHC4
TRAOsHVE1xpwuDrGmgJwGj/JOyg8viW3TZ5b8xs8J8uEORhNpNk2GnMMot2ac1gyMTyjOlBMWEng
k9OUZJZDnwGKq61FjsEyZYNMPPTrZpiVOYBw7z5050ZITMzazgztTjNMyTciJrpHSinCli2YdVly
ekowxlLKNIL4iBqFGJ/VBwJRETesaIAIa6Jg+lJkDP30juUv0dLEmvllJyW+TFJFpS1lDLporrBP
YMpDQSSKR9mrI0QikRGifOQiSGgcckRo0gddJ+J1zg1y+lAz2yqZGSjMvkazbGGjOVlxz3yfmwV+
oaI9iricjFKecc8QNNTJzkCKPVB6BE4RE6IGQfQmyyylcrKTM+fSH5Qku5eIJN5UE4DcQZOGT20J
RtsZvpmplJNpDkSkKJX6hiLOGmtAsjnAgjRgkQJkRpgJE4JEGkSZvKk6ejLmy8MvTJ0yQcuaambi
TuTNPHOgpMlTnvm+mjX1BTkQrTwJJLyUBhrkmcmpZXFtMCsqpTj1leTpU6c80e0TJFhKHX7XJiZo
JJ5PczE1cyUi1XM5KTTyDk3N2wDRF4gxpMsBCqoBChxoig6wgLxA4BiXJD6PN88R01n99WdP7yEr
SAvn+g49LH/30DIv/wChknP2BSP6Dj0sf/fQMi//AKGSc/YFLrOIIDmZnHyaemeU+jIyh0c8uWcr
tvLfmtnCXJ9pkZwsmJbPYzOb0gZNybV0v7jEoZOhIubZBmqyKNsJkyM9VTpE5ydTAxcSChTJFzal
0ZGW/JnpBsjCafKVZmYqUoJTM31XOfJ9nOdJedCTIIglXJw4x7xORHmgcAg4wE

看看这个请求:request

这是请求:

private void uploadMeme() {
        RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
        String url = "Hiding this for personal reasons";
        final MemeCreateActivity activity = (MemeCreateActivity) getActivity();
        assert activity != null;
        try {
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("Title", title);
            jsonBody.put("Longtitude", activity.getLon());
            jsonBody.put("Lattitude", activity.getLat());
            jsonBody.put("Picture", activity.getEncodedString());
            final String mRequestBody = jsonBody.toString();
            Log.d(mRequestBody, "Request:");
            JsonObjectRequest stringRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    activity.nextView();

                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    parseVolleyError(error);
                }
            }) {
                @Override
                public String getBodyContentType() {
                    return "application/json; charset=utf-8";
                }

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    //Sets Request headers
                    Map<String, String> headers = new HashMap<>();
                    headers.put("Accept", "application/json");
                    headers.put("Content-Type", "application/json");
                    headers.put("Authorization", "Bearer " + activity.getUser().getJwt());
                    return headers;
                }

                @Override
                public byte[] getBody() {
                    try {
                        return mRequestBody == null ? null : mRequestBody.getBytes("utf-8");
                    } catch (UnsupportedEncodingException uee) {
                        VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, "utf-8");
                        return null;
                    }
                }
            };

            requestQueue.add(stringRequest);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

【问题讨论】:

    标签: java android image bitmap base64


    【解决方案1】:

    Java 用 base64 字符串中的空格解码位图,试试这个:encodedString.replaceAll("\\s+","");

    【讨论】:

      【解决方案2】:

      试试这个:

      public String encodeTobase64(Bitmap image) {
          Bitmap immagex=image;
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          immagex.compress(Bitmap.CompressFormat.JPEG, 100, baos);
          byte[] b = baos.toByteArray();
          String imageEncoded = Base64.encodeToString(b,Base64.DEFAULT);
      
          Log.e("EncodedImage: ", imageEncoded);
          return imageEncoded;
      }
      

      在 onActivityResult() 中使用下面的代码

      InputStream imageStream = null;
              try {
                  imageStream = this.getContentResolver().openInputStream(selectedImage);
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              }
              Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
              encodeTobase64(yourSelectedImage);
      

      【讨论】:

      • 您可能无法在日志中显示整个字符串!或者可能是您的图像已损坏。
      • 我尝试了不同的图像。但这里是字符串:pastebin.com/ebFV1LSh
      • 是的,日志是有限制的,你应该尝试将数据直接保存在txt文件中尝试将其转换回来
      • 我把写入api的函数也放在了原帖中
      【解决方案3】:

      您可以尝试通过您选择的文件的路径获取位图:

      在你的 onActivityResult 中

      Uri targetUri = data.getData();
      String[] filePathColumn = { MediaStore.Images.Media.DATA };
      Cursor cursor = getContentResolver().query(targetUri,
          filePathColumn, null, null, null);
      cursor.moveToFirst();
      
      int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
      //getting the actual path of the file
      String path = cursor.getString(columnIndex);
      cursor.close();
      
      Bitmap bm = BitmapFactory.decodeFile(path);
      
      //your encoding function is ok
      encodedString = encodeImage(selectedImage);
      

      【讨论】:

      • 这给了我一个权限错误:E/BitmapFactory:无法解码流:java.io.FileNotFoundException:/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20190404-WA0009。 jpg(权限被拒绝)
      • 我修复了权限,但我仍然得到一个错误的 base64 字符串。每当我尝试对其进行解码时,我都会得到一个损坏的图像
      • 我使用与encodeImage() 完全相同的代码,它对我有用,也许你的解码器有问题?或者你有错误的文件格式? (即尝试转换 PNG 文件但您使用 bm.compress(Bitmap.CompressFormat.JPEG,100, baos)
      • 我只使用已经压缩的 WhatsApp 图片,我相信它们是 JPG
      • 在原帖中查看我的请求图片
      【解决方案4】:

      是的。我找到了答案。基本上,Android 认为在我的字符串中插入多个空格很有趣。

      通过这样做,您可以将其全部删除:

      activity.getEncodedString().replaceAll("\s+","")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-07
        • 2014-07-21
        • 2014-09-14
        • 2011-02-16
        • 2013-07-04
        • 2016-08-30
        • 1970-01-01
        相关资源
        最近更新 更多