|
@@ -148,7 +148,11 @@ Page({
|
|
|
for (let i = 0; i < tempFiles.length; i++) {
|
|
|
const file = tempFiles[i];
|
|
|
if (file.size <= 10 * 1024 * 1024) {
|
|
|
- validFiles.push(file);
|
|
|
+ // 为每个文件添加唯一标识
|
|
|
+ validFiles.push({
|
|
|
+ ...file,
|
|
|
+ uid: `${Date.now()}_${Math.random().toString(36).substr(2, 9)}_${i}`
|
|
|
+ });
|
|
|
} else {
|
|
|
wx.showToast({
|
|
|
title: '图片大小不能超过10M',
|
|
@@ -159,65 +163,117 @@ Page({
|
|
|
|
|
|
if (validFiles.length > 0) {
|
|
|
wx.showLoading({
|
|
|
- title: '图片压缩中...',
|
|
|
+ title: '图片处理中...',
|
|
|
mask: true
|
|
|
});
|
|
|
|
|
|
- let processedFiles = new Array(validFiles.length);
|
|
|
+ // 创建副本保存待处理的图片列表
|
|
|
+ const filesToProcess = [...validFiles];
|
|
|
+ // 使用Map结构存储结果,确保不会丢失
|
|
|
+ let processedFilesMap = new Map();
|
|
|
let processCount = 0;
|
|
|
|
|
|
+ // 获取当前已有图片的路径列表,用于去重检查
|
|
|
+ const existingPaths = that.data.imageList.map(img =>
|
|
|
+ typeof img === 'string' ? img : img.tempFilePath
|
|
|
+ );
|
|
|
+
|
|
|
// 处理每个图片
|
|
|
- validFiles.forEach((file, index) => {
|
|
|
+ filesToProcess.forEach((file) => {
|
|
|
+ // 检查是否已经存在相同路径的图片
|
|
|
+ if (existingPaths.includes(file.tempFilePath)) {
|
|
|
+ console.log("跳过重复图片:", file.tempFilePath);
|
|
|
+ processCount++;
|
|
|
+
|
|
|
+ // 检查是否所有图片都已处理完成
|
|
|
+ if (processCount === filesToProcess.length) {
|
|
|
+ finishProcessing();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
that.compressImage(file.tempFilePath).then(compressedPath => {
|
|
|
processCount++;
|
|
|
- // 获取压缩后图片的信息
|
|
|
- wx.getFileInfo({
|
|
|
- filePath: compressedPath,
|
|
|
- success: (fileInfo) => {
|
|
|
- console.log('原始大小:', file.size / 1024, 'KB');
|
|
|
- console.log('压缩后大小:', fileInfo.size / 1024, 'KB');
|
|
|
-
|
|
|
- // 在对应位置添加压缩后的图片路径
|
|
|
- processedFiles[index] = {
|
|
|
- tempFilePath: compressedPath,
|
|
|
- size: fileInfo.size
|
|
|
- };
|
|
|
-
|
|
|
- // 检查是否所有图片都已处理完成
|
|
|
- if (processCount === validFiles.length) {
|
|
|
- // 过滤掉可能的空值,并按顺序合并
|
|
|
- let newImageList = that.data.imageList.concat(processedFiles.filter(item => item));
|
|
|
- that.setData({
|
|
|
- imageList: newImageList
|
|
|
- });
|
|
|
- wx.hideLoading();
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.error('获取文件信息失败:', err);
|
|
|
- processCount++;
|
|
|
- // 如果失败,也要检查是否处理完所有图片
|
|
|
- if (processCount === validFiles.length) {
|
|
|
- wx.hideLoading();
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+
|
|
|
+ // 如果返回路径与原路径不同,则认为已成功压缩
|
|
|
+ if (compressedPath !== file.tempFilePath) {
|
|
|
+ // 使用Map结构通过uid存储处理结果,保证一一对应
|
|
|
+ processedFilesMap.set(file.uid, {
|
|
|
+ tempFilePath: compressedPath,
|
|
|
+ size: file.size, // 这里使用原始大小,实际上压缩后大小会变小
|
|
|
+ uid: file.uid,
|
|
|
+ originalPath: file.tempFilePath // 保存原始路径以便追踪
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 如果路径没变,可能是压缩失败或无需压缩的小图片
|
|
|
+ processedFilesMap.set(file.uid, {
|
|
|
+ tempFilePath: compressedPath,
|
|
|
+ size: file.size,
|
|
|
+ uid: file.uid
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否所有图片都已处理完成
|
|
|
+ if (processCount === filesToProcess.length) {
|
|
|
+ finishProcessing();
|
|
|
+ }
|
|
|
}).catch(err => {
|
|
|
console.error('图片压缩失败:', err);
|
|
|
processCount++;
|
|
|
- if (processCount === validFiles.length) {
|
|
|
- wx.hideLoading();
|
|
|
+
|
|
|
+ // 即使压缩失败,也将原图添加到结果中
|
|
|
+ processedFilesMap.set(file.uid, {
|
|
|
+ tempFilePath: file.tempFilePath,
|
|
|
+ size: file.size,
|
|
|
+ uid: file.uid
|
|
|
+ });
|
|
|
+
|
|
|
+ if (processCount === filesToProcess.length) {
|
|
|
+ finishProcessing();
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ // 统一处理添加图片到列表的逻辑
|
|
|
+ function finishProcessing() {
|
|
|
+ // 将Map转换为数组,保持原有顺序
|
|
|
+ let processedFiles = filesToProcess.map(file => processedFilesMap.get(file.uid)).filter(Boolean);
|
|
|
+
|
|
|
+ // 再次检查去重,防止压缩后的图片路径与已有图片重复
|
|
|
+ let currentImagePaths = that.data.imageList.map(img =>
|
|
|
+ typeof img === 'string' ? img : img.tempFilePath
|
|
|
+ );
|
|
|
+
|
|
|
+ let newFiles = processedFiles.filter(file =>
|
|
|
+ !currentImagePaths.includes(file.tempFilePath)
|
|
|
+ );
|
|
|
+
|
|
|
+ console.log(`添加 ${newFiles.length} 张新图片,跳过 ${processedFiles.length - newFiles.length} 张重复图片`);
|
|
|
+
|
|
|
+ if (newFiles.length > 0) {
|
|
|
+ let newImageList = that.data.imageList.concat(newFiles);
|
|
|
+ that.setData({
|
|
|
+ imageList: newImageList
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ wx.hideLoading();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- // 使用canvas进行图片压缩
|
|
|
+ // 修改图片压缩函数,确保生成的路径在后续处理中保持一致
|
|
|
compressImage: function(imagePath) {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
+ // 对于已经压缩过的图片(通常路径中会包含"compressed"),直接返回
|
|
|
+ if (imagePath.indexOf("compressed") > -1) {
|
|
|
+ console.log("图片已压缩,直接使用:", imagePath);
|
|
|
+ resolve(imagePath);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// 获取图片信息
|
|
|
wx.getImageInfo({
|
|
|
src: imagePath,
|
|
@@ -227,6 +283,14 @@ Page({
|
|
|
filePath: imagePath,
|
|
|
success: (fileInfo) => {
|
|
|
const originalSize = fileInfo.size / 1024; // 原始大小,单位KB
|
|
|
+
|
|
|
+ // 如果原图已经很小(小于300KB),可以直接使用
|
|
|
+ if (originalSize < 300) {
|
|
|
+ console.log("图片较小,无需压缩:", originalSize, "KB");
|
|
|
+ resolve(imagePath);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// 根据原图大小确定压缩质量
|
|
|
let targetQuality = 0.8; // 默认压缩质量
|
|
|
|
|
@@ -252,6 +316,7 @@ Page({
|
|
|
.exec((canvasRes) => {
|
|
|
if (!canvasRes || !canvasRes[0] || !canvasRes[0].node) {
|
|
|
// 如果找不到canvas节点,则返回原图
|
|
|
+ console.log("找不到canvas节点,使用原图");
|
|
|
resolve(imagePath);
|
|
|
return;
|
|
|
}
|
|
@@ -284,6 +349,10 @@ Page({
|
|
|
ctx.clearRect(0, 0, targetWidth, targetHeight);
|
|
|
// 绘制图片
|
|
|
ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
|
|
|
+
|
|
|
+ // 生成带有标记的压缩后路径名称
|
|
|
+ const compressedName = `compressed_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
|
|
|
+
|
|
|
// 压缩参数
|
|
|
const compressOptions = {
|
|
|
canvas: canvas,
|
|
@@ -292,57 +361,24 @@ Page({
|
|
|
destWidth: targetWidth,
|
|
|
destHeight: targetHeight,
|
|
|
fileType: 'jpg',
|
|
|
- quality: targetQuality
|
|
|
+ quality: targetQuality,
|
|
|
+ // 添加压缩标记
|
|
|
+ filePath: `${wx.env.USER_DATA_PATH}/${compressedName}.jpg`
|
|
|
};
|
|
|
|
|
|
- // 第一次尝试压缩
|
|
|
- const tryCompress = (quality, attempt = 1) => {
|
|
|
- compressOptions.quality = quality;
|
|
|
-
|
|
|
- wx.canvasToTempFilePath({
|
|
|
- ...compressOptions,
|
|
|
- success: (result) => {
|
|
|
- // 检查压缩后的大小
|
|
|
- wx.getFileInfo({
|
|
|
- filePath: result.tempFilePath,
|
|
|
- success: (compressedInfo) => {
|
|
|
- const compressedSize = compressedInfo.size / 1024; // 压缩后大小,单位KB
|
|
|
- console.log(`压缩后大小 (质量:${quality})`, compressedSize, 'KB');
|
|
|
- // 如果压缩后大小仍大于500KB且尝试次数未达上限,继续压缩
|
|
|
- if (compressedSize > 500 && attempt < 3) {
|
|
|
- // 递减质量
|
|
|
- const newQuality = Math.max(0.1, quality - 0.2);
|
|
|
- console.log(`尝试重新压缩,质量降低至${newQuality}`);
|
|
|
- tryCompress(newQuality, attempt + 1);
|
|
|
- }
|
|
|
- // 如果压缩后小于200KB且质量非最高,尝试提高质量
|
|
|
- else if (compressedSize < 200 && quality < 0.9 && attempt < 3) {
|
|
|
- // 递增质量
|
|
|
- const newQuality = Math.min(0.9, quality + 0.2);
|
|
|
- console.log(`尝试重新压缩,质量提高至${newQuality}`);
|
|
|
- tryCompress(newQuality, attempt + 1);
|
|
|
- }
|
|
|
- else {
|
|
|
- // 返回压缩后的图片
|
|
|
- resolve(result.tempFilePath);
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (error) => {
|
|
|
- console.error('获取压缩后图片信息失败:', error);
|
|
|
- resolve(result.tempFilePath);
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- fail: (error) => {
|
|
|
- console.error('Canvas转图片失败:', error);
|
|
|
- // 如果转换失败则返回原图
|
|
|
- resolve(imagePath);
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- // 开始尝试压缩
|
|
|
- tryCompress(targetQuality);
|
|
|
+ // 执行一次压缩
|
|
|
+ wx.canvasToTempFilePath({
|
|
|
+ ...compressOptions,
|
|
|
+ success: (result) => {
|
|
|
+ console.log("压缩成功,新路径:", result.tempFilePath);
|
|
|
+ resolve(result.tempFilePath);
|
|
|
+ },
|
|
|
+ fail: (error) => {
|
|
|
+ console.error('Canvas转图片失败:', error);
|
|
|
+ // 如果转换失败则返回原图
|
|
|
+ resolve(imagePath);
|
|
|
+ }
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
image.onerror = () => {
|
|
@@ -369,9 +405,13 @@ Page({
|
|
|
|
|
|
previewImage: function (e) {
|
|
|
let index = e.currentTarget.dataset.index;
|
|
|
+ let urls = this.data.imageList.map(item => {
|
|
|
+ // 处理不同格式的图片对象
|
|
|
+ return typeof item === 'string' ? item : item.tempFilePath;
|
|
|
+ });
|
|
|
wx.previewImage({
|
|
|
- current: this.data.imageList[index],
|
|
|
- urls: this.data.imageList
|
|
|
+ current: urls[index],
|
|
|
+ urls: urls
|
|
|
});
|
|
|
},
|
|
|
|