From a812e18e63846522c3a931e6d456b46d3d96350a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E5=8F=B8git?= <240241002@qq.com> Date: Fri, 23 Jan 2026 18:34:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(images):=20=E6=B7=BB=E5=8A=A0=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=88=86=E8=BE=A8=E7=8E=87=E6=A3=80=E6=B5=8B=E4=B8=8E?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=8E=8B=E7=BC=A9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加图片分辨率检测,提示用户图片超过2K分辨率 - 对大于2K分辨率图片进行自动缩放压缩,确保宽高不超过2048 - 在生成Base64时保持图片原格式,非PNG格式转为JPEG并设定压缩质量为0.9 - 优化上传流程,避免因大图影响性能和加载速度 - 提示文字及状态更新,提升用户体验 --- static/js/main.js | 59 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/static/js/main.js b/static/js/main.js index bf6fb24..83d0613 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -373,6 +373,22 @@ function handleNewFiles(files) { const newFiles = Array.from(files).filter(f => f.type.startsWith('image/')); if (newFiles.length === 0) return; + // 检查分辨率并提示压缩 + let largeFound = false; + Promise.all(newFiles.map(file => new Promise(resolve => { + const url = URL.createObjectURL(file); + const img = new Image(); + img.onload = () => { + if (img.width > 2048 || img.height > 2048) largeFound = true; + URL.revokeObjectURL(url); + resolve(); + }; + img.onerror = resolve; + img.src = url; + }))).then(() => { + if (largeFound) showToast('检测到图片分辨率大于 2K,将为您自动压缩至 2K 分辨率', 'info'); + }); + // 如果处于设置器模式,严格限制为 1 张 if (isSetterActive) { if (newFiles.length > 0) { @@ -505,16 +521,51 @@ document.getElementById('submitBtn').onclick = async () => { try { let image_data = []; - // 1. 将图片转换为 Base64 + // 1. 将图片转换为 Base64 (并压缩过大图片) if (uploadedFiles.length > 0) { btnText.innerText = "正在准备图片数据..."; - const readFileAsBase64 = (file) => new Promise((resolve, reject) => { + const processImageFile = (file) => new Promise((resolve, reject) => { const reader = new FileReader(); - reader.onload = () => resolve(reader.result); + reader.onload = (e) => { + const img = new Image(); + img.onload = () => { + const maxDim = 2048; + let w = img.width; + let h = img.height; + + if (w <= maxDim && h <= maxDim) { + resolve(e.target.result); + return; + } + + if (w > h) { + if (w > maxDim) { + h = Math.round(h * (maxDim / w)); + w = maxDim; + } + } else { + if (h > maxDim) { + w = Math.round(w * (maxDim / h)); + h = maxDim; + } + } + + const canvas = document.createElement('canvas'); + canvas.width = w; + canvas.height = h; + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0, w, h); + // 保持原格式,如果不是 png 则默认 jpeg (0.9 质量) + const outType = file.type === 'image/png' ? 'image/png' : 'image/jpeg'; + resolve(canvas.toDataURL(outType, 0.9)); + }; + img.onerror = reject; + img.src = e.target.result; + }; reader.onerror = reject; reader.readAsDataURL(file); }); - image_data = await Promise.all(uploadedFiles.map(f => readFileAsBase64(f))); + image_data = await Promise.all(uploadedFiles.map(f => processImageFile(f))); } // 2. 并行启动多个生成任务