咱们经常在选择完图片后须要对图片进行处理,包括格式转换以及压缩等,最近遇到此场景,故整理汇总为以下: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); }); }