(Java) 解決使用 base64編碼 保存到本地的圖片出現破損的問題。 另:將base64編碼圖片上傳至本地/OSS。

上週使用 base64 上傳圖片到OSS中的時候,發現保存的圖片出現顯示馬賽克和圖片破損打不開的情況。找了很久也沒有出現問題,今天在找答案的時候,偶然間發現有個博主分享的內容完美的解決了我的問題(這裏特別感謝這位博主的分享),所以特此記錄一下,希望能夠幫助遇到同樣問題卻又苦苦掙扎的朋友們。

關於 base64編碼 保存的圖片無法正常顯示的問題,需要注意兩點:

1)上傳使用的 base64編碼 只需要 “data:image/png;base64,”(這個是指圖片的格式,也有可能是“data:image/jpeg;base64,”等)之後的字符串,所以一定要去掉這個前綴。

備註:截取的時候可以使用 base64字符串.substring(base64字符串.indexOf(",") + 1) 方法;

2)如果第一點已經確認寫的沒問題,但是圖片仍然顯示有問題(我就是這個問題),那麼可以繼續往下看:

Postman/Ajax (我是使用Postman的時候出現的問題) 在傳 base64編碼 的時候,會把 base64編碼 中的 "+" 號換成空格,所以需要先將base64中的空格轉換回來,再進行保存操作!

 

下面是使用 base64編碼 上傳的工具類:

public static String getBase64ToImg(String userPhoto,String userId){

        Date date = new Date();
        SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM-dd");

        String newUserPhoto = null;

        // 判斷base64編碼是否爲空
        if(StringUtils.notNull(userPhoto)){	// base64編碼不爲空

            // 1)截取獲取到的base64編碼,去掉前綴"data:image/png;base64," || "data:image/jpeg;base64,",只取base64編碼
            // 2)需要將 base64編碼 中的空格轉換成 + 號
            userPhoto = userPhoto.substring(userPhoto.indexOf(",") + 1).replaceAll(" ", "+");

            try {
                
                newUserPhoto = "images/" + sft.format(date).toString() + "/" + userId + ".png"; 

                //Base64解碼
                BASE64Decoder decoder = new BASE64Decoder();
                byte[] photoBase64 = decoder.decodeBuffer(userPhoto);
                for(int i=0;i<photoBase64.length;++i)
                {
                    if(photoBase64[i]<0)
                    {//調整異常數據
                        photoBase64[i]+=256;
                    }
                }

                /* 保存到本地 如果要保存到OSS中,這個塊可以不用寫 begin*/
                // 創建當前日期的文件件
                File file = new File("images/" + sft.format(date).toString() + "/");
                file.mkdirs();

                newUserPhoto = "images/" + sft.format(date).toString() + "/" + userId +".png"; //新生成的圖片
                OutputStream out = new FileOutputStream(newUserPhoto);
                out.write(photoBase64);
                out.flush();
                out.close();
                /* 保存到本地 end*/


                /* 上傳至OSS 如果需要將圖片上傳至OSS,只需要在 Base64解碼 之後,直接調用OSS的SDK即可,不需要再保存到本地  begin*/
                // Endpoint以杭州爲例,其它Region請按實際情況填寫。
                String endpoint = "http://oss-cn-beijing.aliyuncs.com";
                // 雲賬號AccessKey有所有API訪問權限,建議遵循阿里雲安全最佳實踐,創建並使用RAM子賬號進行API訪問或日常運維,請登錄 https://ram.console.aliyun.com 創建。
                String accessKeyId = "xxxxxxx";
                String accessKeySecret = "xxxxxxxx";
                String bucketName = "images";

                // 創建OSSClient實例。
                OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);

                // 上傳Byte數組。
                ossClient.putObject(bucketName, newUserPhoto, new ByteArrayInputStream(photoBase64));

                // 關閉OSSClient。
                ossClient.shutdown();
                /* 上傳至OSS 如果需要將圖片上傳至OSS,只需要在 Base64解碼 之後,直接調用OSS的SDK即可,不需要再保存到本地  end*/

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return newUserPhoto;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章