由於最近項目作一個webApp的頁面,須要上傳圖片,總結了一下,思路以下:web
1、監聽一個 input (type='file') 的 change 事件,而後拿到文件的 file;算法
<input id="img-input" class="upload-input" type="file" accept="image/*" id="imgbox" multiple/>
2、把 file 轉成 dataURL;canvas
/** * file 轉成 dataURL * @param file 文件 * @param callback 回調函數 */ function fileToDataURL (file, callback) { const reader = new window.FileReader(); reader.onload = function (e) { callback(e.target.result); }; reader.readAsDataURL(file); }
3、而後用 canvas 繪製圖片,繪製的時候通過算法按比例裁剪,而後再把 canvas 轉成 dataURL;api
/** * 使用 canvas 壓縮 dataURL * @param dataURL * @param ratio * @param callback */ function compressDataURL (dataURL, ratio, callback) { const img = new window.Image(); img.src = dataURL; // onload img.onload = function () { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 100 * ratio.w; canvas.height = 100 * ratio.h; const RATIO = canvas.width / canvas.height; let cutx = 0; let cuty = 0; let cutw = img.width; let cuth = img.height; if (cutw / cuth > RATIO) { // 寬超過比例了]] let realw = cuth * RATIO; cutx = (cutw - realw) / 2; cutw = realw; } else if (cutw / cuth < RATIO) { // 長超過比例了]] let realh = cutw / RATIO; cuty = (cuth - realh) / 2; cuth = realh; } ctx.drawImage(img, cutx, cuty, cutw, cuth, 0, 0, canvas.width, canvas.height); const ndata = canvas.toDataURL('image/jpeg', 1); callback(ndata); }; }
4、 dataURL 轉成 blob;app
/** * dataURL 轉成 blob * @param dataURL * @return blob */ function dataURLtoBlob (dataURL) { let binaryString = atob(dataURL.split(',')[1]); let arrayBuffer = new ArrayBuffer(binaryString.length); let intArray = new Uint8Array(arrayBuffer); let mime = dataURL.split(',')[0].match(/:(.*?);/)[1] for (let i = 0, j = binaryString.length; i < j; i++) { intArray[i] = binaryString.charCodeAt(i); } let data = [intArray]; let result; try { result = new Blob(data, { type: mime }); } catch (error) { window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if (error.name === 'TypeError' && window.BlobBuilder){ var builder = new BlobBuilder(); builder.append(arrayBuffer); result = builder.getBlob(type); } else { throw new Error('暫不支持'); } } return result; }
5、把 blob append 到 FormData 的實例對象,而後上傳。函數
var imgBox =document.getElementById("imgbox");
var blobArr = []; //參數能夠傳給後臺 imgBox.change = function(e){ var file=this.files; for(var i=0;i<event.target.files.length;i++){ fileToDataURL(file[i], function(dataURL){ compressDataURL(dataURL,function (newDataURL) { const newBlob = this.dataURLtoBlob(newDataURL,file[i]); //const fileOfBlob = new File([newBlob], file[i].name); //可將blob轉換成file格式 blobArr.push(newBlob); }); }); } }
//上傳
var formData = new FormData();
for (var i = 0, len = blobArr.file.length; i < len; i++) {
formData.append("file" + i, options.file[i]);
}