fix: 图片上传增加压缩(1024px/JPEG 0.7),对齐 AgnesAIDesktop 方案
问题: 上传图片后 AI 无法识别,回复没有图像分析工具 根因: 原图 base64 直接发送(5-10MB),Agnes AI 可能因体积过大拒绝处理 对比 AgnesAIDesktop(可正常工作): - 上传后用 canvas 压缩: max 1024px, JPEG quality 0.7 - 小图(<500KB且尺寸未超标)保留原图 修复: - ChatInput 新增 compressImage 函数(来自 AgnesAIDesktop 验证方案) - processFile 中图片读取后立即压缩再存 preview
This commit is contained in:
@@ -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<string>((resolve) => {
|
||||
// 图片转 base64 data URL → 压缩(限制 1024px, JPEG 0.7)
|
||||
const dataUri = await new Promise<string>((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<string>((resolve) => {
|
||||
@@ -309,3 +310,39 @@ function AttachmentPreview({ attachment, onRemove }: { attachment: Attachment; o
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩图片:限制最大边长,输出 JPEG base64。
|
||||
* 小图(< 500KB 且尺寸未超标)直接返回原图,避免重复编码。
|
||||
*
|
||||
* @see AgnesAIDesktop — 已验证 Agnes AI 可正常处理压缩后的图片
|
||||
*/
|
||||
function compressImage(
|
||||
dataUri: string,
|
||||
maxSize: number,
|
||||
quality: number,
|
||||
): Promise<string> {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user