From 4924e2d339a1c38c816128422599842d311ccae2 Mon Sep 17 00:00:00 2001 From: thzxx Date: Sat, 27 Jun 2026 22:27:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8E=8B=E7=BC=A9(1024px/JPEG=200.7)?= =?UTF-8?q?=EF=BC=8C=E5=AF=B9=E9=BD=90=20AgnesAIDesktop=20=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 上传图片后 AI 无法识别,回复没有图像分析工具 根因: 原图 base64 直接发送(5-10MB),Agnes AI 可能因体积过大拒绝处理 对比 AgnesAIDesktop(可正常工作): - 上传后用 canvas 压缩: max 1024px, JPEG quality 0.7 - 小图(<500KB且尺寸未超标)保留原图 修复: - ChatInput 新增 compressImage 函数(来自 AgnesAIDesktop 验证方案) - processFile 中图片读取后立即压缩再存 preview --- src/components/chat/ChatInput.tsx | 41 +++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/components/chat/ChatInput.tsx b/src/components/chat/ChatInput.tsx index 94eea31..cd56ac1 100644 --- a/src/components/chat/ChatInput.tsx +++ b/src/components/chat/ChatInput.tsx @@ -69,12 +69,13 @@ export function ChatInput(): React.JSX.Element { const attachment: Attachment = { id: `att_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`, file, type }; if (type === 'image') { - // 图片转 base64 data URL - attachment.preview = await new Promise((resolve) => { + // 图片转 base64 data URL → 压缩(限制 1024px, JPEG 0.7) + const dataUri = await new Promise((resolve) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.readAsDataURL(file); }); + attachment.preview = await compressImage(dataUri, 1024, 0.7); } else if (type === 'text') { // 文本文件读取内容 attachment.textContent = await new Promise((resolve) => { @@ -309,3 +310,39 @@ function AttachmentPreview({ attachment, onRemove }: { attachment: Attachment; o ); } + +/** + * 压缩图片:限制最大边长,输出 JPEG base64。 + * 小图(< 500KB 且尺寸未超标)直接返回原图,避免重复编码。 + * + * @see AgnesAIDesktop — 已验证 Agnes AI 可正常处理压缩后的图片 + */ +function compressImage( + dataUri: string, + maxSize: number, + quality: number, +): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => { + let { width, height } = img; + if (width <= maxSize && height <= maxSize && dataUri.length < 500 * 1024) { + resolve(dataUri); + return; + } + if (width > height) { + if (width > maxSize) { height = Math.round((height * maxSize) / width); width = maxSize; } + } else { + if (height > maxSize) { width = Math.round((width * maxSize) / height); height = maxSize; } + } + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d')!; + ctx.drawImage(img, 0, 0, width, height); + resolve(canvas.toDataURL('image/jpeg', quality)); + }; + img.onerror = () => reject(new Error('图片加载失败')); + img.src = dataUri; + }); +}