vue 图片压缩 转 base64 上传图片
因业务需求,公司项目需要用到 图片上传,压缩,转 base64,而这些都是在前台实现的。我之前也没在 vue 里写过这种逻辑和代码,在我的耐心钻研下,终于交付了代码和功能。
现在想把代码发布出来,分享给大家!!!
前端页面
一丶template
<template>
<div class="identityID">
<x-header :left-options="{backText: ''}" :title="this.$route.meta.title"></x-header>
<div class="toptip">
<span>为了保证联盟内用户安全需要对您身份进行验证,您的个人信息将完全保密。</span>
</div>
<flow>
<flow-state is-done title="身份证"></flow-state>
<flow-line :line-span="48"></flow-line>
<flow-state title="驾驶证"></flow-state>
<flow-line :line-span="48"></flow-line>
<flow-state title="行驶证"></flow-state>
</flow>
<div class="content">
<p class="title">拍摄身份证</p>
<div class="imgbox">
<img :src="IDc1" alt="">
<img :src="IDc0" alt="">
<span class="ltitle" v-show="IDc1T">拍摄正面</span>
<span class="rtitle" v-show="IDc0T">拍摄反面</span>
<input accept="image/png,image/jpeg,image/jpg" class="idimg" id="IDc1" name="IDc1" type="file"
v-on:change="uploadIMG($event)">
<input accept="image/png,image/jpeg,image/jpg" class="idimg" id="IDc0" name="IDc0" type="file"
v-on:change="uploadIMG($event)">
</div>
<p class="tip">注意:拍摄上传身份证照片需要保证清晰度,以免造成认证不通过。</p>
</div>
<div class="nextstp" v-if="canNext <=1">
下一步
</div>
<div @click="next" class="CanNextstp" v-if="canNext ===2">
下一步
</div>
<div class="toast" v-transfer-dom>
<loading :show="show1" :text="text1"></loading>
</div>
</div>
</template>
二丶vue js 部分
图片处理部分分为
1丶读取上传文件
2丶转换 base64 编码
3丶使用 canvas 压缩图片
4丶上传图片
<script>
import { Alert, Flow, FlowLine, FlowState, Loading, TransferDomDirective as TransferDom, XHeader } from 'vux'
import * as types from '@store/mutation-types'
export default {
directives: {
TransferDom
},
created() {
},
data() {
return {
imgList: [],
base64img: '',
IDc1: '/static/IDc1.png',
IDc0: '/static/IDc0.png',
IDc1T: true,
IDc0T: true,
imgUrl: '',
canNext: 0,
picavalue: '',
show1: false,
text1: ''
}
},
components: {
Flow,
FlowState,
FlowLine,
XHeader,
Alert,
Loading
},
methods: {
uploadIMG(e) {
this.show1 = true
this.text1 = '正在解析图片'
let files = e.target.files || e.dataTransfer.files
let id = e.target.id
if (!files.length) return
this.picavalue = files[0]
console.log(this.picavalue.size / 1024)
if (this.picavalue.size / 1024 > 10240) {
this.$vux.alert.show({
title: '温馨提示',
content: '图片过大,请重新上传'
})
} else {
this.text1 = '正在获取图片'
this.imgPreview(this.picavalue, id)
}
},
//获取图片
imgPreview(file, id) {
this.text1 = '正在压缩图片'
let self = this
//判断支不支持FileReader
if (!file || !window.FileReader) return false
if (/^image/.test(file.type)) {
//创建一个reader
let reader = new FileReader()
//将图片转成base64格式
reader.readAsDataURL(file)
//读取成功后的回调
reader.onloadend = function() {
let result = this.result
let img = new Image()
img.src = result
console.log('********未压缩前的图片大小********')
console.log(result.length / 1024)
img.onload = function() {
let data = self.compress(img, 0.3)
self.uploadImg(data, id)
}
}
}
},
// 压缩图片
compress(img, size) {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
let initSize = img.src.length
let width = img.width
let height = img.height
canvas.width = width
canvas.height = height
// 铺底色
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, width, height)
//进行最小压缩
let ndata = canvas.toDataURL('image/jpeg', size)
console.log('*******压缩后的图片大小*******')
// console.log(ndata)
console.log(ndata.length / 1024)
return ndata
},
uploadImg(base64, id) {
this.text1 = '正在上传图片'
let body = {
'type': 'userAuth',
'picBase64': base64
}
this.$store.dispatch(types.UPLOAD_IDIMG_INFO, body).then(res => {
this.imgUrl = res.url
if (id === 'IDc1') {
this.IDc1 = this.imgUrl
this.IDc1T = false
this.canNext++
this.$store.commit('saveIdCardFrontUrl', this.imgUrl)
}
if (id === 'IDc0') {
this.IDc0 = this.imgUrl
this.IDc0T = false
this.canNext++
this.$store.commit('saveIdCardBackUrl', this.imgUrl)
}
this.text1 = '图片上传完成'
let _this = this
setTimeout(function() {
// console.log(1111)
_this.hideToast()
}, 800)
})
},
hideToast() {
this.show1 = false
},
next() {
this.$router.push('/home/identityDI')
},
}
}
</script>
三丶css 样式
采用 less 编写
使用了 vux 组件,含部分修改组件样式代码
<style lang="less">
.identityID .vux-header {
position: fixed;
width: 100%;
top: 0;
z-index: 999;
}
.weui-wepay-flow__bd .weui-wepay-flow__li_done .weui-wepay-flow__state {
background: #FED130;
}
.weui-wepay-flow__line .weui-wepay-flow__process {
background: #FED130;
}
.toast .weui-toast {
min-height: 3.6em;
top: 35%;
}
.nextstp {
width: 90%;
height: 1.22rem;
margin: 60px auto 40px auto;
border-radius: 0.13rem;
color: #fff;
background: #a8a8a8;
font-size: 0.44rem;
text-align: center;
line-height: 1.22rem;
}
.CanNextstp {
width: 90%;
height: 1.22rem;
margin: 60px auto 40px auto;
border-radius: 0.13rem;
color: #fff;
background: #FED130;
font-size: 0.44rem;
text-align: center;
line-height: 1.22rem;
}
.content {
width: 90%;
margin: 0 auto;
.tip {
font-size: 0.42rem;
color: #aaa;
margin-top: 30px;
}
.title {
font-size: 0.48rem;
margin-top: 50px;
}
.imgbox {
position: relative;
margin-top: 30px;
text-align: center;
.idimg {
display: block;
width: 49%;
height: 100%;
opacity: 0;
position: absolute;
top: 0;
}
#IDc1 {
left: 0;
}
#IDc0 {
right: 0;
}
.ltitle, .rtitle {
color: #fff;
font-size: 0.48rem;
position: absolute;
bottom: 15px;
}
.ltitle {
left: 45px;
}
.rtitle {
right: 45px;
}
img {
width: 4.3rem;
height: 4.38rem;
border-radius: 0.13rem;
}
}
}
.toptip {
margin-top: 47px;
width: 100%;
height: 1.39rem;
font-size: 0.39rem;
color: #000;
background: #FFF7D8;
span {
display: block;
width: 90%;
margin: 0 auto;
padding-top: 3.5%;
}
}
</style>
文章到处结束,本人菜鸟一枚,有问题欢迎补充!
欢迎访问博主博客:泽林博客
本作品采用《CC 协议》,转载必须注明作者和本文链接
By: Laravel-China NiZerin
Blog: nizer.in
感谢分享,mark一下
makr一下,感谢
你博客中的评论,感觉会被查水表。

https://www.iacblog.com/2019/12/969.html
@青风百里 感谢提醒,我检查一下