1
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user