【问题标题】:Decompressing Bitmap from Base64 and GZIP从 Base64 和 GZIP 解压缩位图
【发布时间】:2014-07-01 15:32:55
【问题描述】:

在我的应用程序中,我获得了用户的个人资料图片,然后将其作为字符串保存到序列化类中。

我使用下面的代码执行 GZIP 压缩和 Base64,但我无法执行您在下面的 getProfilePicture() 方法中看到的相反操作:

private void saveBitmap(){
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    mBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
    byte[] byteArray = byteArrayOutputStream.toByteArray();
    String bitmapContent = "";
    try {
        bitmapContent = FileHelpers.compressAndBase64(byteArray);
        //later save it...
        } catch (IOException e) {
          e.printStackTrace();
          Log.e(TAG, "Error converting bitmap to gzip and base64");
         }
}


public static String compressAndBase64(byte[] byteArray)
        throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    GZIPOutputStream zos = new GZIPOutputStream(baos);
    zos.write(byteArray);
    zos.close();
    byte[] bytes = baos.toByteArray();
    return Base64.encodeToString(bytes, Base64.DEFAULT);
}

现在我想将它转换回位图...但到目前为止我没有成功。

这些步骤是将字符串从 Base64 解码回字节数组,然后解压缩字节数组并转换为位图。

   public Bitmap getProfilePicture(){

        if(getProfilePhotoBase64() != null) {
            byte[] decoded = Base64.decode(mProfilePhotoBase64.getBytes(), Base64.DEFAULT);
            final int BUFFER_SIZE = 32;
            ByteArrayInputStream is = new ByteArrayInputStream(decoded);
            GZIPInputStream gis = null;
            try {
                gis = new GZIPInputStream(is, BUFFER_SIZE);
            } catch (IOException e) {
                e.printStackTrace();
            }
            StringBuilder string = new StringBuilder();
            byte[] data = new byte[BUFFER_SIZE];
            int bytesRead;
            try {
                while ((bytesRead = gis.read(data)) != -1) {
                    string.append(new String(data, 0, bytesRead));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                gis.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] byteArray = string.toString().getBytes();
            Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,byteArray.length);

            if(bitmap != null) {
                return bitmap;
            } else {
                return null;
            }
        }

        return null;
    }

这是我使用上面的代码得到的错误消息:

--- SkImageDecoder::Factory returned null

我在 PHP 中可以很容易地做到这一点,但在 Java 中很难做到!

if(isset($_POST["photo"])) {

    $photoContent = $_POST["photo"];
    $photo = imap_base64 ($photoContent);
    $photo = gzdecode($photo);

    $filename = $_POST["username"].".png";

    $dir = SITE_ROOT_PATH."/images/".$user."/".$filename;
    file_force_contents($dir, $photo);

} else {
    $filename = "NO_PROFILE_PHOTO";
}

【问题讨论】:

    标签: java android base64 gzip


    【解决方案1】:

    好的,我设法以这种方式解决了问题:

    /**
     * IMPORTANT NOTE!!!!!!!!!!!!!!
     * String is first converted to byte array, then compressed using GZIP and then
     * the resulting byte array is encoded to Base64.DEFAULT
     * @return
     */
    public String getProfilePhotoBase64() {
        return mProfilePhotoBase64;
    }
    
    public Bitmap getProfilePicture(){
        if(getProfilePhotoBase64() != null) {
            byte[] decoded = Base64.decode(mProfilePhotoBase64.getBytes(), Base64.DEFAULT);
    
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ByteArrayInputStream bis = new ByteArrayInputStream(decoded);
    
            GZIPInputStream zis = null;
            try {
                zis = new GZIPInputStream(bis);
                byte[] tmpBuffer = new byte[256];
                int n;
                while ((n = zis.read(tmpBuffer)) >= 0) {
                    bos.write(tmpBuffer, 0, n);
                }
                zis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            Bitmap bitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0
                    , bos.toByteArray().length);
    
            if(bitmap != null) {
                return bitmap;
            } else {
                return null;
            }
        }
        return null;
    }
    

    【讨论】:

    • 你应该说出你改变了什么以及为什么。
    【解决方案2】:

    到底是什么问题? compressAndBase64() 将返回一个空字符串,因为 boas.toByteArray() 将返回 0 个字节,因为 boas 刚刚创建,因此为空。您不需要创建蟒蛇。换个方式

    return Base64.encodeToString(bytes, Base64.DEFAULT); 
    

    return Base64.encodeToString(byteArray, Base64.DEFAULT);
    

    【讨论】:

    • boas.toByteArray() 之前声明过,所以它工作得很好,它压缩和base64位图,但我不能反过来。我可以在php中解压base64和gzip,所以压缩代码工作得很好。
    • 对不起。我监督您将 byteArray 压缩到 boas。但是,如果我使用 encodeToString 进行编码,那么我将使用 decodeFromString 进行解码。或者使用对 encode()/decode()。
    • 没有这种方法(如果有什么不同的话)
    • Base64.decode(mProfilePhotoBase64.getBytes(), 更改为Base64.decode(mProfilePhotoBase64,
    • 哦,我明白了...您正在使用 StringBuilder 并将图像的字节视为字符串。那么你不能那样做。最好把直接读取的数据字节放到byteArray中。
    猜你喜欢
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多