bc518174
王天杨
提交两个项目文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
import type { ComponentPublicInstance } from "vue";
/** 较小分辨率 + 二次 compressImage,适配常见 php.ini 默认 2M 上限 */
const DEST_W = 640;
const DEST_H = 360;
/**
* 将图片按中心裁剪为 16:9,输出约 640×360 JPEG(仅接受横向原图:宽大于高)。
* - H5:canvas + Blob URL(供 uni.uploadFile)
* - 微信小程序:依赖页面内 canvas-id="crop16" 与传入的组件实例
* - 其他端:原图返回
*/
export function cropImageTo16x9(
src: string,
mpInstance?: ComponentPublicInstance | null
): Promise<string> {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src,
success: (info) => {
const iw = info.width;
const ih = info.height;
if (iw <= ih) {
reject(new Error("请上传横向照片(宽需大于高),竖图或方图无法使用"));
return;
}
const ar = 16 / 9;
let sx = 0;
let sy = 0;
let sw = iw;
let sh = ih;
if (iw / ih > ar) {
sw = Math.round(ih * ar);
sx = Math.round((iw - sw) / 2);
} else {
sh = Math.round(iw / ar);
sy = Math.round((ih - sh) / 2);
}
const plat = String(
(import.meta as unknown as { env?: { UNI_PLATFORM?: string } }).env
?.UNI_PLATFORM ?? ""
);
if (plat === "h5" || plat === "web") {
cropH5(src, sx, sy, sw, sh).then(resolve).catch(reject);
return;
}
if (plat === "mp-weixin" && mpInstance) {
cropMpWx(src, sx, sy, sw, sh, mpInstance).then(resolve).catch(reject);
return;
}
resolve(src);
},
fail: (e) => reject(e),
});
});
}
function cropH5(
src: string,
sx: number,
sy: number,
sw: number,
sh: number
): Promise<string> {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => {
try {
const canvas = document.createElement("canvas");
canvas.width = DEST_W;
canvas.height = DEST_H;
const ctx = canvas.getContext("2d");
if (!ctx) {
reject(new Error("canvas"));
return;
}
ctx.drawImage(img, sx, sy, sw, sh, 0, 0, DEST_W, DEST_H);
canvas.toBlob(
(blob) => {
if (!blob) {
reject(new Error("toBlob"));
return;
}
resolve(URL.createObjectURL(blob));
},
"image/jpeg",
0.68
);
} catch (e) {
reject(e);
}
};
img.onerror = () => reject(new Error("图片加载失败"));
img.src = src;
});
}
function cropMpWx(
src: string,
sx: number,
sy: number,
sw: number,
sh: number,
instance: ComponentPublicInstance
): Promise<string> {
return new Promise((resolve, reject) => {
const ctx = uni.createCanvasContext("crop16", instance as any);
ctx.drawImage(src, sx, sy, sw, sh, 0, 0, DEST_W, DEST_H);
ctx.draw(false, () => {
setTimeout(() => {
uni.canvasToTempFilePath(
{
canvasId: "crop16",
destWidth: DEST_W,
destHeight: DEST_H,
fileType: "jpg",
quality: 0.68,
success: (r) => resolve(r.tempFilePath),
fail: (e) => reject(e),
},
instance as any
);
}, 150);
});
});
}
|