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
| export default {
data() {
return {
loader: false,
photoSrc: ''
};
},
methods: {
// 1. 触发文件选择
triggerSelect() {
// 在Uniapp H5中,通过$refs获取原生DOM元素并点击
// 注意:App端不支持此操作,App端请使用 uni.chooseImage
this.$refs.fileInput.click();
},
// 2. 监听文件改变
async handleFileChange(event) {
const files = event.target.files;
if (!files || files.length === 0) return;
this.loader = true;
const file = files[0];
try {
// A. 压缩图片
const { blob, filename } = await this.compressImage(file);
// B. 构造新的File对象 (解决部分浏览器兼容性)
const newFile = new File([blob], filename || 'compressed.jpg', { type: blob.type });
// C. 执行上传业务
await this.uploadProcess(newFile, file.path); // file.path 在H5 input中可能不存在,视业务需求调整
} catch (error) {
console.error("处理失败", error);
this.$u.toast("图片处理失败", 2000);
} finally {
this.loader = false;
// 清空value,确保下次选择同一张图也能触发change事件
event.target.value = '';
}
},
// 3. 核心:图片压缩工具函数 (返回Promise)
compressImage(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
const img = new Image();
img.src = e.target.result;
img.onload = () => {
// 原始尺寸
const originWidth = img.width;
const originHeight = img.height;
// 目标尺寸配置
const maxWidth = 960;
const maxHeight = 1280;
let targetWidth = originWidth;
let targetHeight = originHeight;
// 计算缩放比例
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
// Canvas 绘制
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = targetWidth;
canvas.height = targetHeight;
context.clearRect(0, 0, targetWidth, targetHeight);
context.drawImage(img, 0, 0, targetWidth, targetHeight);
// 导出 Blob
canvas.toBlob((blob) => {
if (blob) {
resolve({ blob, filename: file.name });
} else {
reject(new Error('Canvas to Blob failed'));
}
}, file.type || 'image/jpeg', 0.8); // 0.8 为压缩质量
};
img.onerror = (err) => reject(err);
};
reader.onerror = (err) => reject(err);
});
},
// 4. 上传业务逻辑
async uploadProcess(file, originalPath) {
// 假设 upload, detection, editFacePhoto 已导入或定义
const imgPath = await upload(file, originalPath, `/qy/photo`);
const detectionRes = await detection(imgPath);
const res = await editFacePhoto(detectionRes);
if (res.code === 0) {
this.photoSrc = res.imgUrl;
this.$u.toast("上传成功!", 2000);
} else {
this.$u.toast(res.msg, 3000);
}
}
}
}
|