之前写过一篇关于Golang后端如何对图片进行base64解码并保存至文件服务器的文章传送门,现在补充前端vue框架下如何对图片压缩上传(使用了vant的上传组件)。
选择前端压缩的原因
减轻服务端压力,减少流量。
Vue使用vant的上传组件
<van-cell-group>
<van-cell title="上传图片">
<van-uploader :after-read="uploadImg"
accept="image/gif, image/jpeg ,image/png"
:max-size=6000000
@oversize="overSize" >
<van-icon name="photograph"/>
</van-uploader>
</van-cell>
</van-cell-group>
<div class="show-img">
<div class="item" v-for="(item, index) in imgBase64" :key="index">
<span class="cancel-btn" @click="delImg(index)">x</span>
<img :src="item">
</div>
</div>
//script中定义imgBase64图片数组,存放base64编码的图片
data() {
return {
imgBase64: [],
}
},
复制代码
- 第一段是vant的上传组件,包含uploadImg和overSize方法。
- 第二段用来在页面中展示添加的图片。包含图片数组imgBase64,和删除图片的方法delImg。
uploadImg方法是本文的重点
uploadImg(file) {
// 大于1.5MB的jpeg和png图片都缩小像素上传
if(/\/(?:jpeg|png)/i.test(file.file.type)&&file.file.size>1500000) {
// 创建Canvas对象(画布)
let canvas = document.createElement('canvas')
// 获取对应的CanvasRenderingContext2D对象(画笔)
let context = canvas.getContext('2d')
// 创建新的图片对象
let img = new Image()
// 指定图片的DataURL(图片的base64编码数据)
img.src = file.content
// 监听浏览器加载图片完成,然后进行进行绘制
img.onload = () => {
// 指定canvas画布大小,该大小为最后生成图片的大小
canvas.width = 400
canvas.height = 300
/* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点,400,300是将图片按给定的像素进行缩小。
如果不指定缩小的像素图片将以图片原始大小进行绘制,图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片,最后的图片就是张局部图。*/
context.drawImage(img, 0, 0, 400, 300)
// 将绘制完成的图片重新转化为base64编码,file.file.type为图片类型,0.92为默认压缩质量
file.content = canvas.toDataURL(file.file.type, 0.92)
// 最后将base64编码的图片保存到数组中,留待上传。
if(this.imgBase64.length < 6) {
this.imgBase64.push(file.content)
}else{
alert("最多上传6张图片")
}
}
}else{
// 不做处理的jpg和png以及gif直接保存到数组
if(this.imgBase64.length < 6) {
this.imgBase64.push(file.content)
}else{
alert("最多上传6张图片")
}
}
},
复制代码
当我们用vant的上传图片组件选中一张图片时,就会触发该方法,形参file中包含了content和file对象,content是组件为我们自动处理的base64编码图片,直接就能在网页中显示。图片处理代码中有详细的注释。
最后imgBase64数组收集了所有要上传图片的base64编码,进行上传
//post请求
post(url, data) {
let storage = window.localStorage
return new Promise((resolve) => {
axios({
method: 'post',
url: url,
data: JSON.stringify(data),//将post请求的数据转化为json对象
headers: { 'Authorization': storage.token,'Content-Type': 'application/json; charset=UTF-8'},
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
})
})
},
axios.post(
'/v2/publish',
{
imgList: this.imgBase64
}
)
.then( response => {
)
复制代码
- 第一段代码是我对axios的post方法封装,使用json格式传输给后端。
- 第二段代码是上传请求,给imgBase64数组取了键名imgList,后端根据键名imgList就能拿到图片数组,再进行base64解码就能得到图片然后保存至文件服务器了(在我的另一篇文章有讲)。
本文没有过多的讲解,只是提供一个处理的思路,另外图片的压缩我也只是简单缩小到400宽300高,具体的宽高根据比例来更好。也没有用到所谓的压缩,本质就是将大图缩小然后上传。
所有评论(0)