实际案例可以参考插件市场的 https://ext.dcloud.net.cn/plugin?id=2316
压缩代码
<template>
<view class="compress">
<canvas
canvas-id="compress-canvas"
:style="{ width: canvasSize.width, height: canvasSize.height }"
></canvas>
</view>
</template>
<script>
export default {
data() {
return {
pic: "",
canvasSize: {
width: 0,
height: 0,
},
};
},
methods: {
// 压缩
compressFun(params) {
let that = this;
return new Promise((resolve, reject) => {
// 等待图片信息
that
.getImageInfo(params.src)
.then((info) => {
if (!info) {
reject("获取图片信息异常");
return;
}
// 设置最大 & 最小 尺寸
const maxSize = params.maxSize || 1080;
const minSize = params.minSize || 640;
// 当前图片尺寸
let { width, height } = info;
// 非 H5 平台进行最小尺寸校验
// #ifndef H5
if (width <= minSize && height <= minSize) {
resolve(params.src);
return;
}
// #endif
// 最大尺寸计算
if (width > maxSize || height > maxSize) {
if (width > height) {
height = Math.floor(height / (width / maxSize));
width = maxSize;
} else {
width = Math.floor(width / (height / maxSize));
height = maxSize;
}
}
// 设置画布尺寸
that.$set(that, "canvasSize", {
width: `${width}px`,
height: `${height}px`,
});
// Vue.nextTick 回调在 App 有异常,则使用 setTimeout 等待DOM更新
setTimeout(() => {
const ctx = uni.createCanvasContext("compress-canvas", that);
ctx.clearRect(0, 0, width, height);
ctx.drawImage(info.path, 0, 0, width, height);
try {
ctx.draw(false, () => {
uni.canvasToTempFilePath(
{
x: 0,
y: 0,
width: width,
height: height,
destWidth: width,
destHeight: height,
canvasId: "compress-canvas",
fileType: params.fileType || "png",
quality: params.quality || 0.9,
success: (res) => {
debugger;
// 在H5平台下,tempFilePath 为 base64
resolve(res.tempFilePath);
},
fail: (err) => {
reject(null);
},
},
this
);
});
} catch (error) {
console.error(error);
}
}, 300);
})
.catch(() => {
reject("获取图片信息异常");
});
});
},
// 获取图片信息
getImageInfo(src) {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src,
success: (info) => {
resolve(info);
},
fail: () => {
reject(null);
},
});
});
},
// 批量压缩
compress(params) {
debugger;
// index:进度,done:成功,fail:失败
let [index, done, fail] = [0, 0, 0];
// 压缩完成的路径集合
let paths = [];
// 待压缩的图片
let waitList = [];
if (typeof params.src == "string") {
waitList = [params.src];
} else {
waitList = params.src;
}
// 批量压缩方法
let batch = () => {
return new Promise((resolve) => {
// 开始
let start = async () => {
params.progress &&
params.progress({
done,
fail,
count: waitList.length,
});
// 等待图片压缩方法返回
let path = await next();
if (path) {
done++;
paths.push(path);
} else {
fail++;
}
index++;
// 压缩完成
if (index >= waitList.length) {
resolve(true);
} else {
start();
}
};
start();
});
};
// 依次调用压缩方法
let next = () => {
return this.compressFun({
src: waitList[index],
maxSize: params.maxSize,
fileType: params.fileType,
quality: params.quality,
minSize: params.minSize,
});
};
// 全部压缩完成后调用
return new Promise((resolve, reject) => {
// 批量压缩方法回调
batch()
.then((res) => {
if (res) {
if (typeof params.src == "string") {
resolve(paths[0]);
} else {
resolve(paths);
}
}
})
.catch(() => {
reject(null);
});
});
},
},
};
</script>
<style lang="scss" scoped>
.compress {
position: fixed;
width: 12px;
height: 12px;
overflow: hidden;
top: -99999px;
left: 0;
}
</style>
0 个回复