背景
在vue2项目中引用ant design vue的上传文件的组件,需要对图片进行压缩
具体代码如下
1、template模版中。部分代码在form表单中引用的ant design vue上传组件
<a-form :form="form" ref="addForm">
<a-form-item
label="人脸信息"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
>
<div class="clearfix">
<a-upload
list-type="picture-card"
@preview="handlePreview"
style="width: 600px"
accept="image/*"
:file-list="fileList"
:customRequest="customRequest"
:remove="handleRemove"
:before-upload="beforeUpload"
>
<div v-if="fileList.length < 1">
<a-icon type="plus" />
<div class="ant-upload-text">上传</div>
</div>
</a-upload>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancelImg">
<img alt="人脸" style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</a-form-item>
</a-form>
2、在script中
// 请求接口
<script>
import { sysFileInfoUpload } from '@/api/modular/ykt/getYktData'
import { sysFileInfoPreview } from '@/api/modular/system/fileManage'
export default {
data() {
form: this.$form.createForm(this),
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 18 }
},
proxyPortrait: '',
fileList: [],
previewVisible: false,
previewImage: '',
},
methods: {
/**
* @description: 图片压缩
*/
compressImg(file) {
let disposeFile = file;
if (Object.prototype.toString.call(file) === '[object Blob]') {
disposeFile = new File([file], file.name, { type: file.type });
}
const read = new FileReader(),
_that = this;
// const fileSize = parseFloat(parseInt(disposeFile['size']) / 1024 / 1024).toFixed(2);
// 大小小于0.5Mb之后进行压缩
const fileSize = parseFloat(parseInt(disposeFile['size']) / 1024 / 1024 / 2).toFixed(2);
// 小于1m不压缩
// if (fileSize < 1) return file;
if (fileSize < 0.4) return file;
read.readAsDataURL(disposeFile);
return new Promise((resolve, reject) => {
try {
read.onload = (e) => {
const img = new Image();
img.src = e.target.result;
img.onload = function () {
let w = Math.floor(this.width / 2),
h = Math.floor(this.height / 2);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let base64;
canvas.setAttribute('width', w);
canvas.setAttribute('height', h);
ctx.drawImage(this, 0, 0, w, h);
// console.log(w, h);
// if (fileSize < 1) {
if (fileSize <= 0.4) {
// 如果图片小于一兆 那么不执行压缩操作
base64 = canvas.toDataURL(disposeFile['type'], 1);
// } else if (fileSize > 1 && fileSize < 2) {
} else if (fileSize > 0.4 && fileSize < 1) {
// 如果图片大于1M并且小于2M 那么压缩0.5
base64 = canvas.toDataURL(disposeFile['type'], 0.5);
} else {
// console.log('图片超过2MB')
// 如果图片超过2m 那么压缩0.2
// base64 = canvas.toDataURL(disposeFile['type'], 0.2);
base64 = canvas.toDataURL(disposeFile['type'], 0.1);
}
// console.log(111, _that.dataURLtoFile(base64, disposeFile.name))
resolve(_that.dataURLtoFile(base64, disposeFile.name));
};
};
} catch (error) {
reject(disposeFile);
}
});
},
/**
* @description: 将base64编码转回file文件
*/
dataURLtoFile(dataurl, fileName) {
var 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,
});
},
// 自定义请求
async customRequest(data) {
// 文件
const { file } = data
let newFile = file
// 文件大小 小于0.5Mb之后进行压缩
const fileSize = parseFloat(parseInt(newFile['size']) / 1024 / 1024 / 2).toFixed(2);
// 大于0.4mb 进行压缩
if (fileSize > 0.4) {
// 异步
await this.compressImg(file).then(res => {
newFile = res
})
}
// FileReader这个API将图片转换成base64编码
const reader = new FileReader();
// reader.readAsDataURL(file); // 读取图片文件
reader.readAsDataURL(newFile); // 读取压缩的图片文件 转成image对象
reader.onload = async (file1) => {
const params = {
file: file1.target.result.split(',')[1], // 把 本地图片的base64编码传给后台,调接口
};
// 构建表单数据
let fd = new FormData()
Object.keys(params).forEach(key=>{
fd.append(key,params[key])
})
/* // 打印表单数据
for (var value of fd.values()) {
console.log('表单数据对象', value);
} */
// 调百度接口进行人脸识别 传base64表单数据
await faceDetect(fd).then(res => {
if(res.success) {
// console.log('res', res)
if(res.data) { // 人脸认证通过 人脸识别成功返回true 否则false
const formData = new FormData()
// 转成文件 加名字才可以
formData.append('file', this.dataURLtoFile(file1.target.result, newFile.name))
const listItem = {
uid: '-1',
name: 'image.png',
status: 'done',
url: '',
imageId: '',
}
listItem.uid = data.file.uid
listItem.name = data.file.name
// 上传图片 以文件内容上传
sysFileInfoUpload(formData).then((res) => {
// sysFileInfoUpload(fd).then((res) => {
if (res.success) {
// this.gsList[this.gsList.length - 1].id = res.data
sysFileInfoPreview({ id: res.data }).then((res1) => {
const blob = new Blob([res1])
let imgUrl1 = window.URL.createObjectURL(blob)
listItem.url = imgUrl1
})
listItem.status = 'done'
listItem.imageId = res.data
this.fileList.push(listItem)
} else {
this.$message.warning('上传失败:' + res.message)
listItem.status = 'error'
this.fileList.push(listItem)
this.fileList.map((file) => {
this.handlePreview(file)
})
}
})
} else {
this.$message.warning('人脸识别不成功,请重新上传!')
return
}
}
})
}
},
}
}
</script>