feat(api): 添加Base64图片处理功能

- 在后端API中添加Base64图片处理逻辑,自动去除data URL头部信息
- 处理前端传来的包含header的Base64图片数据

refactor(video.js): 优化图片上传处理流程

- 将图片上传逻辑改为纯前端Base64处理,移除对后端上传接口的依赖
- 实现图片压缩功能,限制最大尺寸为2048像素
- 支持PNG和JPEG格式的图片压缩处理
- 移除原有的文件上传FormData方式,改用直接处理Base64数据
```
This commit is contained in:
24024 2026-02-05 20:47:14 +08:00
parent 85fb484bfa
commit 6cb6f9fc65
2 changed files with 65 additions and 18 deletions

View File

@ -130,6 +130,13 @@ def video_generate():
"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()
task_id = start_async_video_task(app, user_id, payload, cost, model_value)

View File

@ -149,20 +149,59 @@ 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];
// 压缩并转换为 Base64
uploadedImageUrl = await processImageFile(files[0]);
imagePreview.innerHTML = `
<div class="relative w-20 h-20 rounded-xl overflow-hidden border border-indigo-200 shadow-sm group">
<img src="${uploadedImageUrl}" class="w-full h-full object-cover">
@ -172,9 +211,10 @@ document.addEventListener('DOMContentLoaded', () => {
</div>
`;
lucide.createIcons();
}
showToast('图片已就绪', 'success');
} catch (err) {
showToast('图片上传失败', 'error');
console.error(err);
showToast('图片处理失败', 'error');
} finally {
submitBtn.disabled = false;
}