前端進行圖片壓縮並傳入後臺
阿新 • • 發佈:2019-02-07
客戶端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue-demo</title> <style> .input-file { opacity: 0; width: 50px; height: 31px; position: absolute; z-index: 2; } .file-choose { position: absolute; width: 50px; height: 31px; z-index: 1; } .file-show { margin-right: 10px; width: 200px; height: 25px; border-radius: 5px; border: 1px solid #ccc; } .image-lower { display: block; } </style> </head> <body> <input class="file-show"> <button class="file-choose">瀏覽</button> <input type="file" class="input-file" id="file" multiple> <img id="imgLower" class="image-lower"> <button id="upload">上 傳</button> <ul id="fileList"> </ul> <script> var fileDom = document.getElementById("file"); // 需要壓縮的最大尺寸 var MAX_SIZE = 500; var files = []; //監聽檔案選擇事件 fileDom.addEventListener("change", function () { var fileImg = this.files; console.log(fileImg); for (var i = 0; i < fileImg.length; i++) { var file = fileImg[i]; if (!/image\/\w+/.test(file.type)) { alert("請選擇圖片") return false; } //建立一個檔案讀取的工具類 var reader = new FileReader(); //這裡利用了閉包的特性,來保留檔名 (function (x) { reader.onload = function (e) { var liNode = document.createElement("li"); liNode.innerText = x; document.getElementById("fileList").appendChild(liNode); //呼叫壓縮檔案的方法,具體實現邏輯見下面 render(this.result, x); } })(file.name); //告訴檔案讀取工具類讀取那個檔案 reader.readAsDataURL(file); } }, false); function render(src, name) { //建立Image物件 var image = new Image(); image.onload = function () { console.log(image.width,image.height); //通過固定的寬高比壓縮 //寬大於高的情況 if (image.width > MAX_SIZE && image.width >= image.height) { image.height *= MAX_SIZE / image.width; image.width = MAX_SIZE; } //寬小於高的情況 if (image.height > MAX_SIZE && image.height > image.width) { image.width *= MAX_SIZE / image.height; image.height = MAX_SIZE; } var canvas = document.createElement("canvas"); //獲取2d畫布 var ctx = canvas.getContext("2d"); canvas.width = image.width; canvas.height = image.height; ctx.clearRect(0, 0, canvas.width, canvas.height); //繪製圖片 ctx.drawImage(image, 0, 0, image.width, image.height); //生成base64碼 var blob = canvas.toDataURL("image/png"); files.push(blob); document.getElementById("imgLower").src = blob; }; image.src = src; } //監聽上傳按鈕 document.getElementById("upload").addEventListener("click", function () { ajax(); }, false); //ajax請求 var ajax = function () { var xhr = new XMLHttpRequest(); //本地起的伺服器地址為: http://localhost:8080/index xhr.open("POST", "http://localhost:8080/index", true); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //此處為了簡便, 只考慮一個檔案,多個檔案類似 var data = "data=" + files[0]; //將+號轉碼,防止傳輸過程中丟失 xhr.send(data.replace(/\+/g, '%2B')); xhr.onload = function () { console.log(xhr.responseText); } } </script> </body> </html>
服務端:這裡必須要推薦下spring boot,和spring mvc比較起來只有兩個字,省心!!!沒有了複雜的配置和工程結構搭建,簡單的一匹,支援一波。spring boot工程搭建可參考:點我biubiubiu~~~
@RestController @SpringBootApplication public class FileuploadApplication { public static void main(String[] args) { SpringApplicationBuilder builder = new SpringApplicationBuilder(FileuploadApplication.class); builder.bannerMode(Banner.Mode.OFF).run(args); // SpringApplication.run(FileuploadApplication.class, args); } @RequestMapping(value = "/index", method = RequestMethod.POST) public String index(String data, HttpServletRequest request, HttpServletResponse response) throws IOException { String val = request.getParameter("data"); String fileStr = val.split(",")[1]; BASE64Decoder decoder = new BASE64Decoder(); //Base64解碼 byte[] bt = decoder.decodeBuffer(fileStr); // byte[] bt = Base64.decodeBase64(fileStr); BufferedOutputStream bos = null; FileOutputStream fos = null; File file = null; OutputStream out = null; try { file = new File("D:\\"+System.currentTimeMillis()+".png"); for(int i=0;i<bt.length;++i) { if(bt[i]<0) {//調整異常資料 bt[i]+=256; } } out = new FileOutputStream("D:\\"+System.currentTimeMillis()+".png"); out.write(bt); out.flush(); } catch (Exception e) { e.printStackTrace(); }finally { out.close(); } //解決跨域問題 response.setHeader("Access-Control-Allow-Origin", "*"); return "this is a spring boot project"; } }