From dafc4cf0f4f7381fb1ffd35238dd1fabe3b2a987 Mon Sep 17 00:00:00 2001 From: o1key <951565127@qq.com> Date: Mon, 13 Apr 2026 10:49:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=99=E8=95=892?= =?UTF-8?q?=E7=94=BB=E8=8D=89=E5=9B=BE=E5=AF=BC=E8=87=B4=E7=94=9F=E6=88=90?= =?UTF-8?q?2=E5=BC=A0=E5=9B=BE=E7=89=87=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gemini_client: 解析响应时跳过 thought:true 的草稿图,从源头过滤 - 两个香蕉节点的 _images_to_tensor_safe 改为保留最大尺寸图片 Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 7 +++++++ clients/gemini_client.py | 6 +++++- nodes/batch_nano_banana_pro.py | 18 ++++++------------ nodes/nano_banana_pro.py | 18 ++++++------------ 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8ce24f..8b16eb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ --- +## [1.10.4] - 2026-04-13 + +### 修复 +- 修复香蕉2画草图导致生成2张图片问题 + +--- + ## [1.10.3] - 2026-04-13 ### 修复 diff --git a/clients/gemini_client.py b/clients/gemini_client.py index 58aac61..941e4a6 100644 --- a/clients/gemini_client.py +++ b/clients/gemini_client.py @@ -318,10 +318,14 @@ class GeminiAPIClient(BaseAPIClient): inline_data_key = "inlineData" if inline_data_key: + # 跳过思考链草稿图(thought:true 标记的 inlineData 为模型自检用途,非最终输出) + if part.get("thought") is True: + continue + inline_data = part[inline_data_key] # 同样兼容 data/mimeType 的命名 img_data = inline_data.get("data") or inline_data.get("data", "") - + if img_data: img = decode_base64_to_pil(img_data) images.append(img) diff --git a/nodes/batch_nano_banana_pro.py b/nodes/batch_nano_banana_pro.py index eff51b0..cade6da 100644 --- a/nodes/batch_nano_banana_pro.py +++ b/nodes/batch_nano_banana_pro.py @@ -74,32 +74,26 @@ def _images_to_tensor_safe(images: List[Image.Image], node_label: str) -> torch. """ 将 PIL Image 列表转换为 ComfyUI tensor,安全处理多张不同尺寸的情况。 - ComfyUI 的 IMAGE tensor 格式为 [B, H, W, C],要求 batch 内所有图尺寸相同。 - 当 API 返回多张不同分辨率的图时(主图 + 附图),直接 stack 会崩溃。 - 策略: - - 所有图均已按原始分辨率保存到磁盘(调用此函数前已完成) - - 以第一张图的尺寸为基准,只将尺寸相同的图纳入 tensor 输出 - - 尺寸不同的图跳过(不 resize、不丢弃磁盘文件),并打印日志提示 - - 若没有任何图与第一张尺寸相同(极罕见),则只输出第一张 + - 以像素数最大的图尺寸为基准 + - 只输出与最大尺寸相同的图,其余较小的图丢弃 """ if not images: placeholder = Image.new('RGB', (512, 512), color=(128, 128, 128)) return pil_to_tensor([placeholder]) - base_size = images[0].size # PIL size = (W, H) + base_size = max(images, key=lambda img: img.size[0] * img.size[1]).size matched = [img for img in images if img.size == base_size] skipped = [img for img in images if img.size != base_size] if skipped: sizes_str = ", ".join(f"{img.size[0]}×{img.size[1]}" for img in skipped) print( - f"{node_label}: API 额外返回了 {len(skipped)} 张不同尺寸的图 ({sizes_str})," - f"已按原始分辨率保存到磁盘,tensor 输出仅包含与主图尺寸相同的 {len(matched)} 张 " - f"({base_size[0]}×{base_size[1]})" + f"{node_label}: 丢弃 {len(skipped)} 张较小尺寸的图 ({sizes_str})," + f"仅输出最大尺寸 {base_size[0]}×{base_size[1]} 的 {len(matched)} 张" ) - return pil_to_tensor(matched if matched else [images[0]]) + return pil_to_tensor(matched) class BatchNanoBananaPro: diff --git a/nodes/nano_banana_pro.py b/nodes/nano_banana_pro.py index 7ace0eb..495e29d 100644 --- a/nodes/nano_banana_pro.py +++ b/nodes/nano_banana_pro.py @@ -65,32 +65,26 @@ def _images_to_tensor_safe(images: List[Image.Image], node_label: str) -> torch. """ 将 PIL Image 列表转换为 ComfyUI tensor,安全处理多张不同尺寸的情况。 - ComfyUI 的 IMAGE tensor 格式为 [B, H, W, C],要求 batch 内所有图尺寸相同。 - 当 API 返回多张不同分辨率的图时(主图 + 附图),直接 stack 会崩溃。 - 策略: - - 所有图均已按原始分辨率保存到磁盘(调用此函数前已完成) - - 以第一张图的尺寸为基准,只将尺寸相同的图纳入 tensor 输出 - - 尺寸不同的图跳过(不 resize、不丢弃磁盘文件),并打印日志提示 - - 若没有任何图与第一张尺寸相同(极罕见),则只输出第一张 + - 以像素数最大的图尺寸为基准 + - 只输出与最大尺寸相同的图,其余较小的图丢弃 """ if not images: placeholder = Image.new('RGB', (512, 512), color=(128, 128, 128)) return pil_to_tensor([placeholder]) - base_size = images[0].size # PIL size = (W, H) + base_size = max(images, key=lambda img: img.size[0] * img.size[1]).size matched = [img for img in images if img.size == base_size] skipped = [img for img in images if img.size != base_size] if skipped: sizes_str = ", ".join(f"{img.size[0]}×{img.size[1]}" for img in skipped) print( - f"{node_label}: API 额外返回了 {len(skipped)} 张不同尺寸的图 ({sizes_str})," - f"已按原始分辨率保存到磁盘,tensor 输出仅包含与主图尺寸相同的 {len(matched)} 张 " - f"({base_size[0]}×{base_size[1]})" + f"{node_label}: 丢弃 {len(skipped)} 张较小尺寸的图 ({sizes_str})," + f"仅输出最大尺寸 {base_size[0]}×{base_size[1]} 的 {len(matched)} 张" ) - return pil_to_tensor(matched if matched else [images[0]]) + return pil_to_tensor(matched) class NanoBananaPro: