前言:哈喽,朋友们,最近一直在马不停蹄地赶项目,很久没有写博客了。今天我们来看一下前端上传图片地时候如何对图片进行压缩
1、图片上传
我近期写项目都是使用的VUE,这里上传图片使用了Element-ui这个组件库
具体代码如下:
<el-upload class="avatar-uploader" action="https://jsonplaceholder.typicode.com/posts/" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> <style> .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409EFF; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } </style> <script> export default { data() { return { imageUrl: '' }; }, methods: { handleAvatarSuccess(res, file) { this.imageUrl = URL.createObjectURL(file.raw); }, beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpeg'; const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPG) { this.$message.error('上传头像图片只能是 JPG 格式!'); } if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); } return isJPG && isLt2M; } } } </script>
2、选取合适的钩子
这个组件为我们提供了许多钩子
on-preview | 点击文件列表中已上传的文件时的钩子 | function(file) | — | — |
on-remove | 文件列表移除文件时的钩子 | function(file, fileList) | — | — |
on-success | 文件上传成功时的钩子 | function(response, file, fileList) | — | — |
on-error | 文件上传失败时的钩子 | function(err, file, fileList) | — | — |
on-progress | 文件上传时的钩子 | function(event, file, fileList) | — | — |
on-change | 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 | function(file, fileList) | — | — |
before-upload | 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。 | function(file) | — | — |
before-remove | 删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除。 | function(file, fileList) | — | — |
我这里选择了before-upload这个钩子,在图片上传前对图片进行压缩
3、对图片进行压缩操作
beforeAvatarUpload(file) { const isJPG = file.type === "image/jpeg" || file.type === "image/png"; const isLt2M = file.size / 1024 / 1024 < 100; if (!isJPG) { this.$message.error("上传头像图片只能是 jpg、png 格式!"); } if (!isLt2M) { this.$message.error("上传头像图片大小不能超过 100MB!"); } if (!isJPG || !isLt2M) { return false; } let me = this; let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function(e) { //图片大于100K压缩 if (file.size > 1024 * 1024 * 0.1) { let img = new Image(); img.src = this.result; img.onload = function() { let originWidth = img.width; let originHeight = img.height; let canvas = document.createElement("canvas"); let context = canvas.getContext("2d"); canvas.width = 512; //压缩后的宽度 canvas.height = (originHeight * canvas.width) / originWidth; context.drawImage(img, 0, 0, canvas.width, canvas.height); me.form.image = canvas.toDataURL("image/jpeg"); }; } else { me.form.image = this.result; } }; return false; //isJPG && isLt2M; },
这里使用的canvas对图片进行压缩,其原理是通过canvas结合js重新绘制一副 2d 图片,然后给canvas画布设置宽高来完成目标图片的压缩。
以上。