前言:

随着现在手机像素,拍照功能越来越好,随之而来的是本地图片越来越大,那么如何更好的将本地图片上传到后端接口呢?这是后台管理系统常见的场景和头疼的问题,这里分享下个人的方法。

实现效果:

如下图所示,从 580kb -> 压缩后 150kb

实现步骤:

1、父级引入封装文件

//页面上//js中data() {return {compressImgVisible: false,}

2、首先实现上传功能,使用el-upload,

封装uploadImg.vue

//element的上传图片,压缩图片组件export default {props:{/** * 自动上传参数 * */autoUpload:{ // 是否需要选取完自动上传功能type: Boolean,default: true},// 默认图片,父级传过来 http开头的文件mrImgUrl:{type: String,default: ''},action:{//上传的地址type: String,default: ''},headers: {//设置上传的请求头部type:Object,default: () => {return {}}},data: {//上传时额外带的参数type:Object,default: () => {return {}}},name:{//上传的文件字段名type: String,default: 'file'},cookieOK:{//支持发送 cookie 凭证信息type: Boolean,default: true},/** * 公共参数 * */showFileList:{//是否显示已上传文件列表type: Boolean,default: false},drag:{//是否启用拖拽上传type: Boolean,default: false},accept:{//接受文件类型-图片上传类型-不同的格式之间以逗号隔开type: String,default: '.jpg,.jpeg,.png'},listType:{ // 文件列表的类型 - text/picture/picture-cardtype: String,default: 'picture-card'},fileList:{//已上传的文件列表,type:Array,default: () => {return [{name: 'food.jpeg',url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg" />HTMLCanvasElement.toDataURL()

具体方法:其中dataUrl 就是拿到的canvas图片的base64地址

 /** * @压缩公共方法 * @params file * @return 压缩后的文件,支持两种,file和 blob */compressImg(file) {const reader = new FileReader();// readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,// 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。reader.readAsDataURL(file);reader.onload = () => {const img = new Image();img.src = reader.result;img.onload = () => {// 图片的宽高const w = img.width;const h = img.height;const canvas = document.createElement("canvas");// canvas对图片进行裁剪,这里设置为图片的原始尺寸canvas.width = w;canvas.height = h;const ctx = canvas.getContext("2d");// canvas中,png转jpg会变黑底,所以先给canvas铺一张白底ctx.fillStyle = "#fff";// fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在// (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。ctx.fillRect(0, 0, canvas.width, canvas.height);// 绘制图像ctx.drawImage(img, 0, 0, w, h);// canvas转图片达到图片压缩效果// 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,// 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。const dataUrl = canvas.toDataURL("image/jpeg", 0.8);this.dialogImageUrl = dataUrl};};},

4、拿到的base64地址,不能直接给后端,要转格式,这里提供两种,一是file文件,跟压缩前的格式一样,还有一种是blob方法

// canvas生成的格式为base64,需要进行转化, base64->filedataURLtoFile(dataurl,fileName) {let arr = dataurl.split(','),mime = arr[0].match(/:(.*" />

实现源码(上传+压缩):

uploadImg.vue

源图片大小:{{ sourceFile.size/1024 }} kb点我压缩压缩图片大小:{{compressFile.size/1024 }} kb//element的上传图片,压缩图片组件export default {props:{/** * 自动上传参数 * */autoUpload:{ // 是否需要选取完自动上传功能type: Boolean,default: true},// 默认图片,父级传过来 http开头的文件mrImgUrl:{type: String,default: ''},action:{//上传的地址type: String,default: ''},headers: {//设置上传的请求头部type:Object,default: () => {return {}}},data: {//上传时额外带的参数type:Object,default: () => {return {}}},name:{//上传的文件字段名type: String,default: 'file'},cookieOK:{//支持发送 cookie 凭证信息type: Boolean,default: true},/** * 公共参数 * */showFileList:{//是否显示已上传文件列表type: Boolean,default: false},drag:{//是否启用拖拽上传type: Boolean,default: false},accept:{//接受文件类型-图片上传类型-不同的格式之间以逗号隔开type: String,default: '.jpg,.jpeg,.png'},listType:{ // 文件列表的类型 - text/picture/picture-cardtype: String,default: 'picture-card'},fileList:{//已上传的文件列表,type:Array,default: () => {return [{name: 'food.jpeg',url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg" />filedataURLtoFile(dataurl,fileName) {let arr = dataurl.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new File([u8arr], fileName, {type:mime})},// canvas生成的格式为base64,需要进行转化, base64->blobdataURLtoBlob(dataurl) {const arr = dataurl.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]);let n = bstr.length;const u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime });},},}.uploadImgBody{height: auto;.upload-image{width:200px;height: 200px;.fileImg{width:100%;height: 100%;}}.showImg{width:100px;height: 100px;}}

更多资料:

前端压缩图片上传_泡泡大怪兽的博客-CSDN博客

前端图片压缩(几乎无损)_蓝格子.的博客-CSDN博客_前端无损压缩