目录文章目录前言实践总结 前言 上传图片/视频/文件是我们经常会遇到的问题,但是一旦图片过大就会导致不好的操作体验。 图片上传是前端中常见的的业务场景。无论是前台还是后台,适当的对图片进行压缩处理,可以显著的提升用户体验。 而在后台管理系统中,图片压缩不仅仅能够提升后台管理员操作体验,更是可以防止后台设置过大的图片导致前台图片加载过久,从而影响用户体验。 实践 先看下面两张图片,它们表面看上去是一模一样的,但实际上各自所占用的内存大小相差了 180 倍。 经过对比,图片并没有明显的失真情况,下面给大家分享一下,我的解决方法。 具体的思路是: 通过 FormData 构造函数创建一个空对象,将图片绘制到 canvas 画布上,然后再进行压缩。用户上传的文件超过一定的大小后就可以执行压缩的操作,当然如果图片太小的话,我们就没必要再压了。建议采用宽高等比例的方式来压缩,不然可能会出现图片变形的情况。 这里我采用 element 的文件上传控件来上传图片: <el-upload :action="GLOBAL.serverFileUrl" name="file" drag :show-file-list="false" :on-change="beforeAvatarUpload" > <i ></i> </el-upload> 定义了三个事件方法: //图片上传之前处理事件 beforeAvatarUpload(file) { console.log(file); const isJpgPng = file.raw.type === "image/jpeg" || file.raw.type === "image/png"; if (!isJpgPng ) { this.GLOBAL.messageEvent("error","上传头像图片只能是 JPG/PNG 格式!"); } else { this.compressImg(file.raw); } return isJpgPng; }, compressImg(file) { let that = this; // ?通过 FormData 构造函数创建一个空对象 let formData = new FormData(); let reader = new FileReader(); // ?将读取到的文件编码成 DataURL reader.readAsDataURL(file); // ?压缩图片 reader.onload = function(ev) { try { // ?读取图片来获得上传图片的宽高 let img = new Image(); img.src = ev.target.result; img.onload = function(ev) { // ?将图片绘制到 canvas 画布上进行压缩 let canvas = document.createElement("canvas"); let context = canvas.getContext("2d"); let imgwidth = img.width; let imgHeight = img.height; // ?按比例缩放后图片宽高; let targetwidth = imgwidth; let targetHeight = imgHeight; // ?/如果原图宽大于最大宽度 if (targetWidth > targetHeight) { // ?原图宽高比例 let scale = targetHeight / 1280; targetHeight = 1280; targetWidth' = targetwidth / scale; } else { // ?原图宽高比例 let scale = targetWidth / 1280; targetWidth = 1280; targetHeight = targetHeight / scale; } // ?缩放后高度仍然大于最大高度继续按比例缩小 canvas.width = targetwidth; //canvas 的宽=图片的宽 canvas.height = targetHeight; //canvas 的高=图片的高 context.clearRect(0,0, canvas.width, canvas.height); context.drawImage(this, 0, 0, canvas.width, canvas.height); let data = "": // ?如果图片小于 0.6Mb,不进行压缩,并返回二进制流 if (file.size <= 628288) { data = canvas.toDataURL("image/jpeg"); formData.append("file", file); that.handleChange(file); } // ?如果图片大于 e.6Mb,进行压缩,并返回二进制流 else { // todo 压缩文件大小比例 data = canvas.toDataURL("image/jpeg",0.4); let paper = that.GLOBAL.dataURLtoFile(data, file.name); formData.append("file", paper); that.handleChange(paper); } }; } catch (error) { console.log("出现错误",error); } }; }, // todo 调用上传接口 文件提交给后台 handleChange(file) ( let formData = new FormData( ); formData.append("file",file.raw || file); console.log(formData); brandServices.uploadFile(formData).then(res => { if (res.data.errno === 0) { this.imgUrl = res.data.data; this.dialogImageUrl = URL.createObjectURL(file); this.GLOBAL.messageEvent("success",res.data.message); } else { this.GLOBAL .messageEvent("error",res .data.message); } }); } 总结 先进行图片上传前的验证;接着再对图片实现压缩的操作;最后就可以把文件流提交给后台。