项目中由于后台接口的原因,写了两种上传方式
1.自动上传
2.手动上传
针对这两种方式,记录下,如何压缩上传图片
模板代码:
<el-upload
class="upload-demo marginBom"
:action="fileUrl + 'file'"
:data="{
customerId: clientTableRowData.id,
sourceId: clientTableRowData.id,
sourceTable: 'harmonize_customer',
}"
:on-success="fileUpSuc"
:on-error="fileUpErr"
:show-file-list="false"
:before-upload="beforeUpload"
:headers="myHeaders"
>
<el-button
v-if="clientTableRowData.stopStatus !== 1"
type="primary"
icon="el-icon-plus"
size="mini"
>添加附件</el-button
>
<!-- <div slot="tip" class="el-upload__tip">
只能上传jpg/png文件,且不超过500kb
</div> -->
</el-upload>
使用before-upload这个钩子函数,上传之前做什么,这里用到一个插件 image-Conversion
1.安装
npm i image-conversion --save
2.需要压缩的vue文件引用
import * as imageConversion from 'image-conversion';
上传前处理压缩图片的完整代码
beforeUpload(file) {
const _that = this
const isJpgOrPng =
file.type === "image/jpeg" || file.type === "image/png";
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJpgOrPng) {
this.$message.error("上传图片只能是 JPG 或 PNG 格式!");
return false;
}
return new Promise((resolve) => {
// 小于2M 不压缩
if (isLt2M) {
resolve(file)
}
// 压缩到400KB,这里的400就是要压缩的大小,可自定义
imageConversion.compressAccurately(file, 400).then((res) => {
console.log(res);
resolve(res);
});
//compressAccurately有多个参数时传入对象
//imageConversion.compressAccurately(file, {
// size: 1024, //图片大小压缩到1024kb
// width:1280 //宽度压缩到1280
//}).then(res => {
//resolve(res)
//})
});
},
before-upload可以接收一个Promise回调,imageConversion它也是异步的。
2.手动上传
接口要以file类型随表单一起提交,这时就不能自动上传了,那么 el-upload组件的auto-upload这个属性就为false.
auto-upload为false 会导致 before-upload失效。但可以用 on-change钩子函数代替
但是这个钩子函数 不能接受Promise回调,所以使用imageConversion异步返回一个resolve结果,没办法接收,所以这里用到另一个压缩图片的方法,使用canvas画布压缩,
下面的压缩函数,可以放到你的公用工具js里
/** 图片压缩,默认同比例压缩
* @param {Object} fileObj
* 图片对象
* 回调函数有一个参数,base64的字符串数据
*/
export function compress(fileObj, callback) {
try {
const image = new Image()
image.src = URL.createObjectURL(fileObj)
image.onload = function() {
const that = this
// 默认按比例压缩
let w = that.width
let h = that.height
const scale = w / h
w = fileObj.width || w
h = fileObj.height || (w / scale)
let quality = 0.7 // 默认图片质量为0.7
// 生成canvas
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
// 创建属性节点
const anw = document.createAttribute('width')
anw.nodeValue = w
const anh = document.createAttribute('height')
anh.nodeValue = h
canvas.setAttributeNode(anw)
canvas.setAttributeNode(anh)
ctx.drawImage(that, 0, 0, w, h)
// 图像质量
if (fileObj.quality && fileObj.quality <= 1 && fileObj.quality > 0) {
quality = fileObj.quality
}
// quality值越小,所绘制出的图像越模糊
const data = canvas.toDataURL('image/jpeg', quality)
// 压缩完成执行回调
const newFile = convertBase64UrlToBlob(data)
callback(newFile)
}
} catch (e) {
console.log('压缩失败!')
}
}
function convertBase64UrlToBlob(urlData) {
const bytes = window.atob(urlData.split(',')[1]) // 去掉url的头,并转换为byte
// 处理异常,将ascii码小于0的转换为大于0
const ab = new ArrayBuffer(bytes.length)
const ia = new Uint8Array(ab)
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
return new Blob([ab], { type: 'image/png' })
}
项目中的实例
模板代码:
<el-upload
class="upload-demo"
ref="uploadPrice"
action="#"
:auto-upload="false"
:on-change="fileChange"
:on-success="priceSuc"
:show-file-list="false"
:limit="5"
multiple
>
<el-button slot="trigger" size="mini" type="primary"
>添加附件</el-button
>
</el-upload>
js:
fileChange(file, fileList) {
this.$refs.uploadPrice.clearFiles();
let _this = this;
let obj = {
imgUrl: "",
name: "",
};
let fileListData = [];
for (let x = 0; x < fileList.length; x++) {
let item1 = fileList[x];
this.GLOBAL.compress(item1.raw, function (val) {
let newfile = new window.File([val], file.name, { type: file.type });
newfile.uid = file.uid;
fileListData.push(newfile);
});
var file = item1.raw;
obj.name = item1.name;
var reader = new FileReader();
reader.onload = function (e) {
//转base64
obj.imgUrl = e.target.result;
_this.fileArr.push(obj);
};
reader.readAsDataURL(file);
}
this.$set(this.form, "fileList", fileListData);
// console.log(this.form.fileList);
},
我是将这个方法注册到全局,压缩函数 返回的val 是Blob类型
如果你的接口要求用file类型 下面的这行代码,将Blob类型转化为file类型
图片的压缩质量可以根据需要调整
以上就是elementUI压缩图片的两个方法,还有其他的好的方法,可以研究下。
本文章转载自 链接: https://blog.csdn.net/pengboran/article/details/116012180