效果: 上传前:
上传后:
压缩效果一览: 代码:
这个文件封装的是图片压缩方法:取名api.js
function dataURLtoFile(dataurl, name) {
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], name.split(".")[0] + ".png", { type: mime });
}
function compressImg(file) {
var src;
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,
h = this.height;
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) {
base64 = canvas.toDataURL(file['type'], 1);
} else if (fileSize > 1 && fileSize < 2) {
base64 = canvas.toDataURL(file['type'], 0.5);
} else {
base64 = canvas.toDataURL(file['type'], 0.2);
}
files = dataURLtoFile(base64, file.name);
resolve(files)
};
};
})
};
export default {
compressImg,
}
将上面图片压缩的文件放到main.js文件中引入,这样可以作为全局的方法,在任何地方使用
import api from '@/provider/common/util/api'
Vue.prototype.$api = api
template模板中:(accept一样要设置成"image/*",才可以拉起相机和相册)
<!-- 宠物头像 -->
<van-field is-link @click='picInput()'>
<template #label>
<span class="color-666666">宠物靓照</span>
</template>
<template #input>
<div class="flex">
<img
:src="faceImg"
alt=""
class="wd-32 ht-32 img-style"
/>
<input
@change="xmTanUploadImg"
id="uploadFile"
type="file"
accept="image/*"
mutiple="mutiple"
ref="uploadFile"
class="file-upload"
/>
</div>
</template>
</van-field>
样式两行:
<style lang="scss" scoped>
.img-style {
border-radius: 50%;
}
.file-upload {
display: none;
}
</style>
vue实例中:
export default {
data() {
return {
faceImg: `${location.origin}/tkpage/T20210801751/static/dog.png`,
id: '',
fileData: {}
}
},
methods: {
picInput() {
this.$refs.uploadFile.click();
},
async xmTanUploadImg(el) {
this.id = '';
var fileData = el.target.files[0];
var fileSize = fileData.size / 1024 / 1024;
if ( fileSize > 10) {
return this.$toast({
message: '图片大小不能超过10M!'
})
}
var f = await this.$api.compressImg(fileData);
console.log(fileData,'图片压缩之前fileData');
console.log(f,'图片压缩之后 fffff');
let formData = new FormData();
formData.append("file", f);
try {
let res = await uploadPicture({
timeout: 1000 * 60 * 100,
headers: {
"Content-Type": "multipart/form-data",
Accept: "*/*",
},
data: formData,
method: "post",
});
if (res.responseCode !== "000_000_000") {
return this.$toast({
message: res.responseMsg,
});
}
this.id = res.responseData.id
this.faceImg = `${location.origin}/hopen/`+ res.responseData.url
} catch (error) {
return this.$toast({
message: "图片上传失败,281",
});
}
}
}
}
上面是接口返回图片地址进行展示。如下代码是在本地预览图片,可适用于图片大小不超过5M的情况下:(本地预览的优点:速度快)
var fileData = el.target.files[0];
var fileSize = fileData.size / 1024 / 1024
if ( fileSize > 10) {
return this.$toast({
message: '图片大小不能超过10M!'
})
}
var that = this;
var reader = new FileReader();
reader.readAsDataURL(fileData);
reader.onload = function (e) {
that.faceImg = e.target.result;
};
开始做的是本地预览,上传过大图片会报错。报错原因:localStorage中最大可存5M内容,而要在本地预览的图片一旦超过5M,就会报这个错。 而我项目中,最大可上传10M图片,所以让后端返回图片链接,在页面上进行展示。
以下是控制台报错提示: Uncaught DOMException: Failed to execute ‘setItem’ on ‘Storage’: Setting the value of ‘vuex’ exceeded the quota.
|