1. 程式人生 > >圖片轉Base64編碼 base64編碼轉圖片

圖片轉Base64編碼 base64編碼轉圖片

這兩天給手機寫了幾個服務(介面形式),其他資料還好,圖片實在沒處理過,這裡記錄下使用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 "";
	}