This commit is contained in:
张成
2026-04-22 10:30:31 +08:00
parent 33ab46aec0
commit ce1f5485fe

View File

@@ -15,7 +15,7 @@ export interface UploadFromWxProps {
async function convert_to_jpg_and_compress( async function convert_to_jpg_and_compress(
src: string, src: string,
{ width, height } { width, height, quality }: { width: number; height: number; quality: number }
): Promise<string> { ): Promise<string> {
const canvas = Taro.createOffscreenCanvas({ type: "2d", width, height }); const canvas = Taro.createOffscreenCanvas({ type: "2d", width, height });
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
@@ -33,22 +33,54 @@ async function convert_to_jpg_and_compress(
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Taro.canvasToTempFilePath({ Taro.canvasToTempFilePath({
canvas: canvas as unknown as Taro.Canvas, canvas: canvas as unknown as Taro.Canvas,
fileType: "png", fileType: "jpg",
quality: 0.7, quality,
success: (res) => resolve(res.tempFilePath), success: (res) => resolve(res.tempFilePath),
fail: reject, fail: reject,
}); });
}); });
} }
function getFileSize(path: string): Promise<number> {
const fs = (Taro as any).getFileSystemManager();
return new Promise((resolve, reject) => {
fs.stat({
path,
success: (res) => resolve(res.stats.size),
fail: reject,
});
});
}
async function compressImage(files) { async function compressImage(files) {
const res: string[] = []; const res: string[] = [];
const qualityList = [0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6];
for (const file of files) { for (const file of files) {
const compressed_image = await convert_to_jpg_and_compress(file.path, { // 小图且体积已在目标范围内时,直接上传原图,避免二次压缩变糊
width: file.width, if (
height: file.height, file.size <= TARGET_IMAGE_SIZE &&
}); file.width <= IMAGE_MAX_SIZE.width &&
res.push(compressed_image); file.height <= IMAGE_MAX_SIZE.height
) {
res.push(file.path);
continue;
}
let bestImage = file.path;
for (const quality of qualityList) {
const compressedImage = await convert_to_jpg_and_compress(file.path, {
width: file.width,
height: file.height,
quality,
});
const compressedSize = await getFileSize(compressedImage);
bestImage = compressedImage;
if (compressedSize <= TARGET_IMAGE_SIZE) {
break;
}
}
res.push(bestImage);
} }
return res; return res;
} }
@@ -58,6 +90,8 @@ const IMAGE_MAX_SIZE = {
width: 1080, width: 1080,
height: 720, height: 720,
}; };
// 压缩目标体积(约 300KB
const TARGET_IMAGE_SIZE = 800 * 1024;
// 标准长宽比,判断标准 // 标准长宽比,判断标准
const STANDARD_ASPECT_RATIO = IMAGE_MAX_SIZE.width / IMAGE_MAX_SIZE.height; const STANDARD_ASPECT_RATIO = IMAGE_MAX_SIZE.width / IMAGE_MAX_SIZE.height;