前言:哈嘍,朋友們,最近一直在馬不停蹄地趕項目,很久沒有寫博客了。今天我們來看一下前端上傳圖片地時候如何對圖片進行壓縮
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畫布設置寬高來完成目標圖片的壓縮。
以上。