Fix OpenAI multi-image node to process mixed image sizes independently
This commit is contained in:
@@ -381,8 +381,8 @@ Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理
|
||||
- `seed` (INT): 随机种子,用于控制生成的随机性
|
||||
- `image_1` ~ `image_6` (IMAGE, 可选): 最多 6 张输入图像
|
||||
- 说明: 用户有几张图就连接几个输入口,无需手动 Batch
|
||||
- 规则: 节点内部会自动收集所有已连接图像,并使用 `torch.cat(..., dim=0)` 合并后逐张编码发送到 API
|
||||
- 注意: 多张图像尺寸需一致,否则会返回尺寸不一致错误
|
||||
- 规则: 节点内部会自动逐张处理每个输入图像,分别编码后发送到 API
|
||||
- 优势: 不要求所有图像尺寸一致,512×512 和 511×768 之类的混合输入也可直接使用
|
||||
- `temperature` (FLOAT, 可选): 采样温度
|
||||
- 默认值: 0.3
|
||||
- 范围: 0.0 ~ 2.0
|
||||
@@ -392,6 +392,10 @@ Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理
|
||||
- `detail` (选择, 可选): 图像分析细节等级
|
||||
- 选项: low, high, auto
|
||||
- 默认值: auto
|
||||
- `image_max_size` (INT, 可选): 单张图像最长边缩放上限
|
||||
- 默认值: 1024
|
||||
- 范围: 256 ~ 4096
|
||||
- 说明: 超过该尺寸的图像会在发送前按比例缩小,以减少 token 消耗与请求体积
|
||||
- `proxy_url` (STRING, 可选): HTTP/HTTPS 代理地址
|
||||
- 示例: `http://127.0.0.1:7890`
|
||||
|
||||
|
||||
Binary file not shown.
+20
-12
@@ -1,4 +1,3 @@
|
||||
import torch
|
||||
import numpy as np
|
||||
import requests
|
||||
import json
|
||||
@@ -76,6 +75,12 @@ class OpenAINode:
|
||||
"detail": (["low", "high", "auto"], {
|
||||
"default": "auto"
|
||||
}),
|
||||
"image_max_size": ("INT", {
|
||||
"default": 1024,
|
||||
"min": 256,
|
||||
"max": 4096,
|
||||
"step": 64
|
||||
}),
|
||||
"proxy_url": ("STRING", {
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
@@ -89,12 +94,19 @@ class OpenAINode:
|
||||
FUNCTION = "generate_content"
|
||||
CATEGORY = "Rui-Node🐶/AI模型🤖"
|
||||
|
||||
def _encode_image_tensor(self, img_tensor):
|
||||
def _encode_image_tensor(self, img_tensor, image_max_size):
|
||||
img_np = img_tensor.cpu().numpy()
|
||||
img_np = np.clip(img_np, 0, 1)
|
||||
img_pil = Image.fromarray((img_np * 255).astype(np.uint8), 'RGB')
|
||||
width, height = img_pil.size
|
||||
if max(width, height) > image_max_size:
|
||||
ratio = image_max_size / max(width, height)
|
||||
img_pil = img_pil.resize(
|
||||
(max(1, int(width * ratio)), max(1, int(height * ratio))),
|
||||
Image.LANCZOS
|
||||
)
|
||||
buffered = io.BytesIO()
|
||||
img_pil.save(buffered, format="JPEG")
|
||||
img_pil.save(buffered, format="JPEG", quality=85)
|
||||
return base64.b64encode(buffered.getvalue()).decode('utf-8')
|
||||
|
||||
def generate_content(
|
||||
@@ -114,6 +126,7 @@ class OpenAINode:
|
||||
temperature=0.3,
|
||||
max_tokens=500,
|
||||
detail="auto",
|
||||
image_max_size=1024,
|
||||
proxy_url=""
|
||||
):
|
||||
"""
|
||||
@@ -132,12 +145,7 @@ class OpenAINode:
|
||||
]
|
||||
|
||||
if not all_images:
|
||||
return ("Error: 至少需要连接一张图像到 image_1 ~ image_6。",)
|
||||
|
||||
try:
|
||||
images = torch.cat(all_images, dim=0)
|
||||
except Exception as e:
|
||||
return (f"Error: 无法合并多张图像,请确保所有输入图像尺寸一致。详细信息: {str(e)}",)
|
||||
return (user_prompt if user_prompt.strip() else "(未提供图片和描述)",)
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": system_prompt}
|
||||
@@ -151,9 +159,9 @@ class OpenAINode:
|
||||
"text": user_prompt
|
||||
})
|
||||
|
||||
for idx in range(images.shape[0]):
|
||||
img_tensor = images[idx]
|
||||
img_base64 = self._encode_image_tensor(img_tensor)
|
||||
for image in all_images:
|
||||
img_tensor = image[0]
|
||||
img_base64 = self._encode_image_tensor(img_tensor, image_max_size)
|
||||
user_content.append({
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
|
||||
Reference in New Issue
Block a user