js前端实现图片压缩上传的示例代码
作者:Winn
这篇文章主要为大家详细介绍了js前端如何实现图片压缩上传的效果,文中的示例代码讲解详细,具有一定的学习价值,有需要的小伙伴可以参考一下
这里有两张图片,它们表面看上去是一模一样的,但实际上各自所占用的内存大小相差了180倍。
可以看到右边的图片是22.3MB,而左侧的图片只有127KB,但是实际上这两张图片的大小都是22.3MB。
最近在开发中遇到这样的一个需求,需要把用户上传的图片先进行一次压缩,然后再保存到服务器,这里我们除了优先考虑压缩图片的大小外,还要顾及图片压缩后的清晰度问题。
经过对比,图片并没有明显的失真情况,下面给大家分享一下,我的解决方法:
这里我采用element的文件上传控件来上传图片
<el-upload class="avatar-uploader" :action="GLOBAL.serverFileUrl" name="file" drag :show-file-list="false" :on-change="beforeAvatarUpload" > <i class="el-icon-plus avatar-uploader-icon"></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); } }); }
总结:
先进行图片上传前的验证;接着再对图片实现压缩的操作;最后就可以把文件流提交给后台。
具体的思路是:通过FormData构造函数创建一个空对象,将图片绘制到canvas画布上,然后再进行压缩。用户上传的文件超过一定的大小后就可以执行压缩的操作,当然如果图片太小的话,我们就没必要再压了。建议采用宽高等比例的方式来压缩,不然可能会出现图片变形的情况。
到此这篇关于js前端实现图片压缩上传的示例代码的文章就介绍到这了,更多相关js图片压缩上传内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!