个人纪录方便自己以后查看 大佬请忽略 本文章出自 ykCoder搬砖方便自己阅读
功能实现原理
在上传图片前获取该图片的文件流(beforeUpload中获取),对这个文件流进行压缩操作,再将压缩后的文件流传过去(resolve(newFile)),最后进行自定义的上传请求(customRequest中实现)。
图片预览方式
前端本地图片的预览则可以选择blob或者base64的方式,本文推荐使用blob方式来预览图片的文件流。
部分代码
html
<template>
<div>
<a-spin :spinning="isShowSpinning">
<img
v-if="imageUrl"
:src="data:imageUrl"
style="width: 200px; height: 200px; margin-right: 10px"
/>
<a-upload
accept="image/*"
:beforeUpload="beforeImageUpload"
:customRequest="customImageRequest"
>
<a-button type="primary"> <a-icon type="upload" />上传 </a-button>
</a-upload>
</a-spin>
</div>
</template>
api
import request from '@/utils/request'
const api = {
uplodBackName: '/biz/uplodBackName'
}
export function getUplodBackName (parameter) {
return request({
url: api.uplodBackName,
method: 'post',
// 传输文件流需要单独设置请求头
headers: {
'Content-Type': 'multipart/form-data'
},
data: parameter
})
}
js
<script>
import { getUplodBackName } from "@/api/biz/manage";
export default {
components: {},
data() {
return {
imageUrl: "",
isShowSpinning: false,
};
},
methods: {
// 上传图片前的钩子函数
beforeImageUpload(file, fileList) {
return new Promise(async (resolve, reject) => {
if (!file.type.includes("image")) {
this.$message.warning("请上传图片");
reject(new Error("请上传图片"));
return;
}
this.isShowSpinning = true;
const newFile = await this.compressImg(file);
resolve(newFile);
});
},
// 自定义的上传请求
customImageRequest(info) {
const { file } = info;
// blob方式预览图片
this.imageUrl = window.URL.createObjectURL(file);
// 组装数据
const formData = new FormData();
formData.append("files", file);
// 发送请求
getUplodBackName(formData)
.then((res) => {
this.$message.success("上传成功");
})
.catch(() => {
this.$message.warning("上传失败");
})
.finally(() => {
this.isShowSpinning = false;
});
},
// base64转码(压缩完成后的图片为base64编码,这个方法可以将base64编码转回file文件)
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(",");
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
},
// 图片压缩函数
compressImg(file) {
const that = this;
var files;
var fileSize = parseFloat(parseInt(file["size"]) / 1024 / 1024).toFixed(
2
);
var read = new FileReader();
read.readAsDataURL(file);
return new Promise(function (resolve, reject) {
read.onload = function (e) {
var img = new Image();
img.src = e.target.result;
img.onload = function () {
// 默认按比例压缩
var w = this.width;
var h = this.height;
// 生成canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var base64;
// 创建属性节点
canvas.setAttribute("width", w);
canvas.setAttribute("height", h);
ctx.drawImage(this, 0, 0, w, h);
if (fileSize < 1) {
// 如果图片小于一兆 那么压缩0.5
base64 = canvas.toDataURL(file["type"], 0.5);
} else if (fileSize > 1 && fileSize < 2) {
// 如果图片大于1M并且小于2M 那么压缩0.5
base64 = canvas.toDataURL(file["type"], 0.5);
} else {
// 如果图片超过2m 那么压缩0.2
base64 = canvas.toDataURL(file["type"], 0.2);
}
// 回调函数返回file的值(将base64编码转成file)
files = that.dataURLtoFile(base64, file.name); // 如果后台接收类型为base64的话这一步可以省略
resolve(files);
};
};
});
},
},
};
</script>