咱們經常在選擇完圖片後須要對圖片進行處理,包括格式轉換以及壓縮等,最近遇到此場景,故整理彙總爲以下:javascript
// 圖片處理, 輸入文件,輸出base64和文件 dealImg(file: File, callback: any) { this.fileToBase64(file, (base64: any) => { this.compressImg(base64, (compressBase64: any) => { callback({ base64, file: this.base64ToFile(compressBase64, file.name) }); }); }); } // 獲取圖片用於展現,輸入文件,輸出base64 fileToBase64(file: File, callback: any) { const fr = new FileReader(); fr.onload = (evt: any) => { callback(evt.target.result); }; fr.readAsDataURL(file); } // 圖片壓縮,輸入base64,輸出base64 compressImg(base64: any, callback: any, w: number = 1000) { const newImage = new Image(); const quality = 0.8; // 壓縮係數0-1之間 newImage.src = base64; newImage.setAttribute("crossOrigin", 'Anonymous'); // url爲外域時須要 let imgWidth; let imgHeight; newImage.onload = function() { // @ts-ignore imgWidth = this.width; // @ts-ignore imgHeight = this.height; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d") as any; if (Math.max(imgWidth, imgHeight) > w) { if (imgWidth > imgHeight) { canvas.width = w; canvas.height = w * imgHeight / imgWidth; } else { canvas.height = w; canvas.width = w * imgWidth / imgHeight; } } else { canvas.width = imgWidth; canvas.height = imgHeight; } ctx.clearRect(0, 0, canvas.width, canvas.height); // @ts-ignore ctx.drawImage(this, 0, 0, canvas.width, canvas.height); const newBase64 = canvas.toDataURL("image/jpeg", quality); callback(newBase64); // 必須經過回調函數返回,不然沒法及時拿到該值 } } // 將base64轉換爲文件格式 base64ToFile(base64: string, fileName: string): File { const arr = base64.split(','); // @ts-ignore const mime = arr[0].match(/:(.*?);/)[1]; const bytes = atob(arr[1]); const bytesLength = bytes.length; const u8arr = new Uint8Array(bytesLength); for (let i = 0; i < bytes.length; i++) { u8arr[i] = bytes.charCodeAt(i); } const blob = new Blob([u8arr], { type: mime }) return new File([blob], fileName, { type: 'image/jpeg' }); }
調用方式以下:java
// 單個文件處理,若是有有多文件能夠遍歷處理 onSingleFileChange(e: any) { const files = e.target.files; this.dealImg(files[0], (result: any) => { console.log(result); }); }