圖片轉Base64編碼 base64編碼轉圖片
阿新 • • 發佈:2019-01-05
這兩天給手機寫了幾個服務(介面形式),其他資料還好,圖片實在沒處理過,這裡記錄下使用base64編碼遇到的坑。。。。
1、圖片轉base64編碼:
public static String getImageStr(String imgUrl) {//將圖片檔案轉化為位元組陣列字串,並對其進行Base64編碼處理 String imgFile = imgUrl;// 待處理的圖片 InputStream in = null; byte[] data = null; // 讀取圖片位元組陣列 try { in = new FileInputStream(imgFile); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } // 對位元組陣列Base64編碼 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data);// 返回Base64編碼過的位元組陣列字串 }
2、base64編碼轉圖片:
public static boolean GenerateImage(String imgStr,String newPath) { // 對位元組陣列字串進行Base64解碼並生成圖片 if (imgStr == null) // 影象資料為空 return false; BASE64Decoder decoder = new BASE64Decoder(); try { // Base64解碼 byte[] b = decoder.decodeBuffer(imgStr); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) {// 調整異常資料 b[i] += 256; } } // 生成jpeg圖片 OutputStream out = new FileOutputStream(newPath); out.write(b); out.flush(); out.close(); return true; } catch (Exception e) { return false; } }
3、上面兩個方法正常使用是沒問題的,但是手機上傳圖片到伺服器需要通過引數的形式傳到介面,操作起來就比較費勁了,我這裡的思路比較笨:手機把base64編碼傳到介面,介面轉成圖片後存到圖片伺服器,資料庫儲存地址,下面看程式碼:
@RequestMapping("/inkinfo/saveOrUpdate") @ResponseBody public Object saveOrUpdateInkinfo(HttpServletRequest request,HttpServletResponse response){ AppMessage appMsg = new AppMessage(); String data; try { //編碼修正(框架存在問題:web.xml中增加字符集的監聽設定未起作用) data = new String(request.getParameter("data").getBytes("iso-8859-1"),"utf-8"); JSONObject map = (JSONObject) JsonUtils.toObejctByJson(data, JSONObject.class); //儲存簽名圖片 SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HHmmss"); String d = String.valueOf(map.get("LINK_INFO")); //設定伺服器圖片儲存地址 String path = "D:/GSDJ_WebFile/"+map.get("USER_ID")+"/"+sdf.format(new Date())+"/"+map.get("CASE_ID")+".jpg"; //建立目錄 File f = new File("D:/GSDJ_WebFile/"+map.get("USER_ID")+"/"+sdf.format(new Date())); f.mkdirs(); //引數修補 d = d.replace(" ", "+"); //本地生成 StringUtil.GenerateImage(d, path); map.put("LINK_INFO",path); //業務資料儲存 licAppService.saveOrUpdateInkinfo(map); //儲存流程 String OPT_CODE = map.get("OPT_CODE")==null?"": map.get("OPT_CODE").toString();//處理程式碼 if(!StringUtil.isNullOrEmpty(OPT_CODE)&&(OPT_CODE.equals("1")||OPT_CODE.equals("242"))) { this.saveOrUpdateLicProcess(appMsg, map); } appMsg.setData(map); return appMsg; } catch (Exception e1) { // TODO Auto-generated catch block appMsg.setCode("E001"); appMsg.setMessage("伺服器異常"); e1.printStackTrace(); return appMsg; } }
引數修補是因為編碼通過request傳到後臺以後編碼種的+全部變成了空格,所以全部替換了(沒找到別的問題之前先這樣用了)如下圖(左邊是正常編碼,右邊是通過引數傳到後臺以後的):
圖片還有一個合理的處理方法:圖片傳入時base64編碼轉成二進位制資料,後臺也不存圖片,二進位制可以直接存到資料庫中,我主要問題卡在介面如何處理二進位制資料上了,等研究出來再來補充這部分。
另外 java post呼叫介面程式碼:
public static String httpURLConnectionPOST (String POST_URL,String param) {
try {
URL url = new URL(POST_URL);
// 將url 以 open方法返回的urlConnection 連線強轉為HttpURLConnection連線 (標識一個url所引用的遠端物件連線)
HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 此時cnnection只是為一個連線物件,待連線中
// 設定連線輸出流為true,預設false (post 請求是以流的方式隱式的傳遞引數)
connection.setDoOutput(true);
// 設定連線輸入流為true
connection.setDoInput(true);
// 設定請求方式為post
connection.setRequestMethod("POST");
// post請求快取設為false
connection.setUseCaches(false);
// 設定該HttpURLConnection例項是否自動執行重定向
connection.setInstanceFollowRedirects(true);
// 設定請求頭裡面的各個屬性 (以下為設定內容的型別,設定為經過urlEncoded編碼過的from引數)
// application/x-javascript text/xml->xml資料 application/x-javascript->json物件 application/x-www-form-urlencoded->表單資料
// ;charset=utf-8 必須要,不然妙兜那邊會出現亂碼【★★★★★】
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
byte[] mydata = param.toString().getBytes("UTF-8");
// 設定請求體的型別
connection.setRequestProperty("Content-Lenth",
String.valueOf(mydata.length));
// 建立連線 (請求未開始,直到connection.getInputStream()方法呼叫時才發起,以上各個引數設定需在此方法之前進行)
connection.connect();
// 建立輸入輸出流,用於往連線裡面輸出攜帶的引數,(輸出內容為?後面的內容)
DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
// 將引數輸出到連線
if(!StringUtil.isNullOrEmpty(param)) {
dataout.write(mydata);
}
// 輸出完成後重新整理並關閉流
dataout.flush();
dataout.close(); // 重要且易忽略步驟 (關閉流,切記!)
// 連線發起請求,處理伺服器響應 (從連接獲取到輸入流幷包裝為bufferedReader)
BufferedReader bf = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
StringBuilder sb = new StringBuilder(); // 用來儲存響應資料
// 迴圈讀取流,若不到結尾處
while ((line = bf.readLine()) != null) {
// sb.append(bf.readLine());
sb.append(line).append(System.getProperty("line.separator"));
}
bf.close(); // 重要且易忽略步驟 (關閉流,切記!)
connection.disconnect(); // 銷燬連線
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}