公司最近有須要壓縮上傳圖片功能,查找了些資料並實現了一把。node
主要用到的原生組件:FileReader、Canvas、Blob、FormDataios
邏輯步驟:web
Code:ajax
this.compressImage(files[0], (file)=>{ console.log(file); const formData = new FormData(); formData.append('file', file, file.name || '上傳圖片.jpeg'); }, $.noop); //壓縮圖片 compressImage = (file, success, error) => { // 圖片小於1M不壓縮 if (file.size < Math.pow(1024, 2)) { return success(file); } const name = file.name; //文件名 const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (e) => { const src = e.target.result; const img = new Image(); img.src = src; img.onload = (e) => { const w = img.width; const h = img.height; const quality = 0.8; // 默認圖片質量爲0.92 //生成canvas const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 建立屬性節點 const anw = document.createAttribute("width"); anw.nodeValue = w; const anh = document.createAttribute("height"); anh.nodeValue = h; canvas.setAttributeNode(anw); canvas.setAttributeNode(anh); //鋪底色 PNG轉JPEG時透明區域會變黑色 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, w, h); ctx.drawImage(img, 0, 0, w, h); // quality值越小,所繪製出的圖像越模糊 const base64 = canvas.toDataURL('image/jpeg', quality); //圖片格式jpeg或webp能夠選0-1質量區間 // 返回base64轉blob的值 console.log(`原圖${(src.length/1024).toFixed(2)}kb`, `新圖${(base64.length/1024).toFixed(2)}kb`); //去掉url的頭,並轉換爲byte const bytes = window.atob(base64.split(',')[1]); //處理異常,將ascii碼小於0的轉換爲大於0 const ab = new ArrayBuffer(bytes.length); const ia = new Uint8Array(ab); for (let i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); } file = new Blob( [ab] , {type : 'image/jpeg'}); file.name = name; success(file); } img.onerror = (e) => { error(e); } } reader.onerror = (e) => { error(e); } }
遇到的一些坑:canvas
結語,壓縮功能比較適合移動端,畢竟PC端帶寬比較好並且不能兼容IE老版本。後端