|
@@ -0,0 +1,87 @@
|
|
|
+/**
|
|
|
+ * 图片压缩
|
|
|
+ */
|
|
|
+export const compressImages = <T extends Record<string, any>>(params: {
|
|
|
+ list: T[];
|
|
|
+ /**
|
|
|
+ * 图片的键名
|
|
|
+ * @default thumb
|
|
|
+ */
|
|
|
+ imgKey?: string;
|
|
|
+ /**
|
|
|
+ * 图片最大宽度
|
|
|
+ */
|
|
|
+ maxWidth?: number;
|
|
|
+ /**
|
|
|
+ * 等比压缩比例
|
|
|
+ */
|
|
|
+ sizeRatio?: number;
|
|
|
+ /**
|
|
|
+ * 画质
|
|
|
+ * @default 0.8
|
|
|
+ */
|
|
|
+ qualityRatio?: number;
|
|
|
+}) => {
|
|
|
+ const {
|
|
|
+ list,
|
|
|
+ imgKey = "thumb",
|
|
|
+ maxWidth,
|
|
|
+ sizeRatio,
|
|
|
+ qualityRatio = 0.8,
|
|
|
+ } = params;
|
|
|
+
|
|
|
+ return Promise.all<{ _thumb: string } & T>(
|
|
|
+ list.map((item) => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ const img = new Image();
|
|
|
+ img.crossOrigin = "anonymous"; // 设置 CORS 属性
|
|
|
+ img.src = item[imgKey];
|
|
|
+
|
|
|
+ img.onload = () => {
|
|
|
+ const canvas = document.createElement("canvas");
|
|
|
+ const ctx = canvas.getContext("2d");
|
|
|
+
|
|
|
+ // 根据传入参数计算新的宽高
|
|
|
+ let newWidth, newHeight;
|
|
|
+ if (sizeRatio) {
|
|
|
+ newWidth = img.width * sizeRatio;
|
|
|
+ newHeight = img.height * sizeRatio;
|
|
|
+ } else if (maxWidth) {
|
|
|
+ newWidth = Math.min(maxWidth, img.width);
|
|
|
+ newHeight = (newWidth / img.width) * img.height;
|
|
|
+ } else {
|
|
|
+ // 如果未指定比例或最大宽度,保持原尺寸
|
|
|
+ newWidth = img.width;
|
|
|
+ newHeight = img.height;
|
|
|
+ }
|
|
|
+
|
|
|
+ canvas.width = newWidth;
|
|
|
+ canvas.height = newHeight;
|
|
|
+
|
|
|
+ // 绘制压缩后的图像
|
|
|
+ ctx?.drawImage(img, 0, 0, newWidth, newHeight);
|
|
|
+
|
|
|
+ canvas.toBlob(
|
|
|
+ (blob) => {
|
|
|
+ if (blob) {
|
|
|
+ const url = URL.createObjectURL(blob);
|
|
|
+ resolve({
|
|
|
+ ...item,
|
|
|
+ _thumb: url,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ reject(new Error("Blob 创建失败"));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "image/jpeg",
|
|
|
+ qualityRatio
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ img.onerror = () => {
|
|
|
+ reject(new Error("图片加载失败:" + item[imgKey]));
|
|
|
+ };
|
|
|
+ });
|
|
|
+ })
|
|
|
+ );
|
|
|
+};
|