From 6cb6f9fc65c660cea13472a1dd4213149f9a8374 Mon Sep 17 00:00:00 2001 From: 24024 <240241002@qq.com> Date: Thu, 5 Feb 2026 20:47:14 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(api):=20=E6=B7=BB=E5=8A=A0Base64?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=A4=84=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在后端API中添加Base64图片处理逻辑,自动去除data URL头部信息 - 处理前端传来的包含header的Base64图片数据 refactor(video.js): 优化图片上传处理流程 - 将图片上传逻辑改为纯前端Base64处理,移除对后端上传接口的依赖 - 实现图片压缩功能,限制最大尺寸为2048像素 - 支持PNG和JPEG格式的图片压缩处理 - 移除原有的文件上传FormData方式,改用直接处理Base64数据 ``` --- blueprints/api.py | 7 +++++ static/js/video.js | 76 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/blueprints/api.py b/blueprints/api.py index 1c2e399..38b51e2 100644 --- a/blueprints/api.py +++ b/blueprints/api.py @@ -129,6 +129,13 @@ def video_generate(): "images": data.get('images', []), "aspect_ratio": data.get('aspect_ratio', '9:16') } + + # 处理 Base64 图片 (去掉 header) + if payload.get("images"): + payload["images"] = [ + img.split(',', 1)[1] if ',' in img else img + for img in payload["images"] + ] # 4. 启动异步视频任务 app = current_app._get_current_object() diff --git a/static/js/video.js b/static/js/video.js index d6faf24..d0a8ceb 100644 --- a/static/js/video.js +++ b/static/js/video.js @@ -149,32 +149,72 @@ document.addEventListener('DOMContentLoaded', () => { showToast('已应用提示词模板', 'success'); }; - // 上传图片逻辑 + // 图片处理辅助函数 + const processImageFile = (file) => new Promise((resolve, reject) => { + const reader = new FileReader(); + 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); + }); + + // 上传图片逻辑 (改为纯前端 Base64 处理) fileInput.onchange = async (e) => { const files = e.target.files; if (files.length === 0) return; - const formData = new FormData(); - formData.append('images', files[0]); - try { submitBtn.disabled = true; - const r = await fetch('/api/upload', { method: 'POST', body: formData }); - const d = await r.json(); - if (d.urls && d.urls.length > 0) { - uploadedImageUrl = d.urls[0]; - imagePreview.innerHTML = ` -
- - + // 压缩并转换为 Base64 + uploadedImageUrl = await processImageFile(files[0]); + + imagePreview.innerHTML = ` +
+ + - `; - lucide.createIcons(); - } +
+ `; + lucide.createIcons(); + showToast('图片已就绪', 'success'); } catch (err) { - showToast('图片上传失败', 'error'); + console.error(err); + showToast('图片处理失败', 'error'); } finally { submitBtn.disabled = false; }