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