Shadow
Vant2.x上传图片并且压缩
废话不多说直接上代码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css" />
<title>Vant2</title>
</head>
<body>
<div id="app">
<van-field name="uploader" label="文件上传">
<template #input>
<van-uploader v-model="fileList" :after-read="afterRead" :max-count="10" accept="image/*" :multiple="false" />
</template>
</van-field>
</div>
<!-- 引入 Vue 和 Vant 的 JS 文件 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js"></script> -->
<script src="vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js"></script>
<script>
// 在 #app 标签下渲染一个按钮组件
const app = new Vue({
el: '#app',
data() {
return {
quality: 0.8, //图片压缩质量
fileList: [],
}
},
methods: {
afterRead(file) {
let _this = this;
// file.status = 'uploading';
// file.message = '上传中...';
const trueFile = file.file;
const size = trueFile.size / 1024;
console.log(`压缩前 ===>${size}k`);
//图片并且大于800k开始压缩
if (/^image/.test(trueFile.type) && size >= 800) {
// 创建一个reader
let reader = new FileReader();
// 将图片2将转成 base64 格式
reader.readAsDataURL(trueFile);
// 读取成功后的回调
reader.onloadend = function() {
let result = this.result;
let img = new Image();
img.src = result;
img.onload = function() {
// 压缩
let data = _this.compress(img, trueFile.name, trueFile.type);
console.log(`压缩后 ===>${data.fileData.size/1024}k`);
file.content = data.base64Data;
file.file = data.fileData;
}
}
}
},
// 压缩图片
compress(img, name, type) {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
//瓦片canvas
let tCanvas = document.createElement('canvas');
let tctx = tCanvas.getContext('2d');
// let initSize = img.src.length;
let width = img.width;
let height = img.height;
//如果图片大于四百万像素,计算压缩比并将大小压至400万以下
let ratio;
if ((ratio = (width * height) / 4000000) > 1) {
// console.log("大于400万像素");
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
//如果图片像素大于100万则使用瓦片绘制
let count;
if ((count = (width * height) / 1000000) > 1) {
//console.log("超过100W像素");
count = ~~(Math.sqrt(count) + 1) //计算要分成多少块瓦片
//计算每块瓦片的宽和高
let nw = ~~(width / count);
let nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio,
0, 0, nw, nh);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
//进行压缩
let ndata = canvas.toDataURL('image/jpeg', this.quality);
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return {
base64Data: ndata,
fileData: this.dataURLtoFile(ndata, name, type)
}
},
//将base64转换为文件
dataURLtoFile(dataurl, name, type) {
name = name ? name : '图片';
type = type ? type : 'jpg';
var arr = dataurl.split(','),
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], name, {
type: type
})
},
}
});
// 通过 CDN 引入时不会自动注册 Lazyload 组件
// 可以通过下面的方式手动注册
Vue.use(vant.Lazyload);
</script>
</html>
执行结果如图所示
代码都有注释,可以直接拿下来使用!
Dcr163的博客
http://dcr163.cn/618.html(转载时请注明本文出处及文章链接)