- 修复ImageParamsBar组件的useEffect逻辑,确保参数正确同步 - 修复chat.tsx中imageParams的初始化,确保所有字段都有值 - 解决二次对话时选择4K但生成2K的问题 - 确保从localStorage恢复的参数能正确传递给ImageParamsBar组件 问题根源: - ImageParamsBar的useEffect只在initialParams存在时执行 - 如果initialParams是undefined,会使用默认值2K - imageParams可能未正确传递,导致参数丢失 修复方案: - 修改useEffect条件判断,使用!== undefined而不是truthy检查 - 确保imageParams始终有完整的默认值结构 - 添加详细的分析报告文档
6.2 KiB
6.2 KiB
GEMINI生图二次对话4K/2K问题分析报告
🔍 问题描述
使用GEMINI模型生图时,在二次对话中选择4K生成的图片,但实际生成的是2K。
📋 代码流程分析
1. 图片参数保存机制
components/chat.tsx (第129-150行):
// 🆕 从 localStorage 读取保存的图片参数
useEffect(() => {
try {
const saved = localStorage.getItem("gemini-image-params");
if (saved) {
setImageParams(JSON.parse(saved));
}
} catch (e) {
console.error("Failed to load image params:", e);
}
}, []);
// 🆕 保存图片参数到 localStorage
const handleImageParamsChange = (params: ImageGenerationParams) => {
setImageParams(params);
try {
localStorage.setItem("gemini-image-params", JSON.stringify(params));
} catch (e) {
console.error("Failed to save image params:", e);
}
console.log("[Chat] Image params updated:", params);
};
结论:✅ 图片参数会保存到 localStorage,并在组件加载时恢复。
2. 图片参数传递流程
components/chat.tsx (第262-263行):
imageParams: imageParamsRef.current || undefined, // 🆕 传递图片参数(使用ref获取最新值)
app/(chat)/api/chat/route.ts (第663行):
imageParams: requestBody.imageParams || { aspectRatio: "auto", imageSize: "2K" },
lib/ai/providers/gemini-image.ts (第621-624行):
// 确保imageSize有值,优先级:用户选择 > 默认2K
const imageParams = {
aspectRatio: options.imageParams?.aspectRatio || "auto",
imageSize: options.imageParams?.imageSize || "2K"
};
结论:✅ 图片参数会从 chat.tsx → chat/route.ts → gemini-image.ts 传递。
3. ImageParamsBar 组件逻辑
components/image-params-bar.tsx (第77-88行):
// 🆕 监听 initialParams 变化,确保状态同步
useEffect(() => {
console.log("[ImageParamsBar] Mount/Update - initialParams:", initialParams);
if (initialParams) {
setParams({
aspectRatio: "auto",
imageSize: "2K",
imageCount: 1,
...initialParams,
});
}
}, [initialParams]);
问题发现:⚠️ 如果 initialParams 是 undefined 或 null,这个 useEffect 不会执行,导致使用组件内部的默认值 "2K"。
组件内部默认值 (第58-63行):
const [params, setParams] = useState<ImageGenerationParams>({
aspectRatio: "auto",
imageSize: "2K", // 默认 2K
imageCount: 1,
...initialParams,
});
🐛 问题根源
问题1:ImageParamsBar 的 useEffect 条件判断
当前代码:
if (initialParams) {
setParams({
aspectRatio: "auto",
imageSize: "2K", // ⚠️ 如果 initialParams 没有 imageSize,会使用默认值 "2K"
imageCount: 1,
...initialParams,
});
}
问题:
- 如果
initialParams是undefined或null,useEffect不会执行 - 如果
initialParams存在但没有imageSize字段,会使用默认值"2K"
问题2:initialParams 可能未正确传递
components/chat.tsx (第1012行):
imageParams={imageParams}
components/multimodal-input.tsx (第884行):
initialParams={imageParams || undefined}
问题:
- 如果
imageParams是null,会传递undefined - 如果
imageParams是空对象{},ImageParamsBar的useEffect会执行,但会使用默认值"2K"
✅ 解决方案
方案1:修复 ImageParamsBar 的 useEffect
修改前:
useEffect(() => {
console.log("[ImageParamsBar] Mount/Update - initialParams:", initialParams);
if (initialParams) {
setParams({
aspectRatio: "auto",
imageSize: "2K",
imageCount: 1,
...initialParams,
});
}
}, [initialParams]);
修改后:
useEffect(() => {
console.log("[ImageParamsBar] Mount/Update - initialParams:", initialParams);
// 始终更新参数,即使 initialParams 是 undefined
setParams({
aspectRatio: "auto",
imageSize: "2K",
imageCount: 1,
...initialParams, // 如果 initialParams 是 undefined,会使用默认值
});
}, [initialParams]);
优点:
- 确保参数始终同步
- 即使
initialParams是undefined,也会使用默认值
缺点:
- 如果
initialParams是undefined,会覆盖用户的选择(但这是预期的行为)
方案2:确保 imageParams 始终有值
修改 components/chat.tsx:
// 确保 imageParams 始终有值
const [imageParams, setImageParams] = useState<ImageGenerationParams>({
aspectRatio: "auto",
imageSize: "2K"
});
// 从 localStorage 读取保存的图片参数
useEffect(() => {
try {
const saved = localStorage.getItem("gemini-image-params");
if (saved) {
const parsed = JSON.parse(saved);
// 确保所有字段都有值
setImageParams({
aspectRatio: "auto",
imageSize: "2K",
imageCount: 1,
...parsed,
});
}
} catch (e) {
console.error("Failed to load image params:", e);
}
}, []);
优点:
- 确保
imageParams始终有值 - 避免传递
undefined或null
📋 推荐修复方案
同时修复两个问题:
- 修复
ImageParamsBar的useEffect:移除if (initialParams)条件判断 - 确保
imageParams始终有值:在chat.tsx中确保imageParams始终是对象
🔍 验证步骤
-
第一次对话:
- 选择4K
- 生成图片
- 检查
localStorage.getItem("gemini-image-params")是否为{"imageSize":"4K",...}
-
二次对话:
- 打开同一个聊天或新聊天
- 检查
imageParams是否为{"imageSize":"4K",...} - 检查
ImageParamsBar的initialParams是否为{"imageSize":"4K",...} - 检查生成的图片是否为4K
🎯 总结
问题根源:
ImageParamsBar的useEffect只在initialParams存在时执行- 如果
initialParams是undefined或null,会使用组件内部的默认值"2K"
解决方案:
- 移除
if (initialParams)条件判断,确保参数始终同步 - 确保
imageParams始终有值,避免传递undefined或null