1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
| #!/usr/bin/env python3
"""
ComfyUI 极简批量图片处理脚本
将工作流JSON和所有配置参数集中在代码头部,开箱即用
"""
import requests
import json
import os
import time
import glob
from pathlib import Path
# ===================== 用户配置区域 =====================
# 注意:所有路径建议使用原始字符串(前面加r)避免转义问题
# 1. 输入输出设置
INPUT_FOLDER = r"D:\CutRes\buzzer" # 输入图片文件夹路径
OUTPUT_FOLDER = r"D:\inCutRes\buzzer" # 输出文件夹路径
WORKFLOW_FILE = "api_workflow.json" # ComfyUI导出的工作流JSON文件
# 2. ComfyUI服务器设置
COMFYUI_SERVER = "http://127.0.0.1:8188" # ComfyUI服务器地址
TIMEOUT = 60 # 单张图片最大处理等待时间(秒)
RETRY_TIMES = 3 # 失败重试次数
# 3. 图片处理设置
IMAGE_EXTENSIONS = ('.png', '.jpg', '.jpeg', '.webp') # 支持的图片格式
OVERWRITE_EXISTING = False # 是否覆盖已存在的输出文件
# 4. 动态参数设置 (根据你的工作流节点参数调整)
CUSTOM_PARAMETERS = {
# 示例参数(根据你的工作流实际参数名修改):
# "denoise": 0.7,
# "steps": 20,
# "cfg_scale": 7.5,
# "seed": -1,
}
# ===================== 主程序 =====================
def main():
# 初始化检查
print("="*50)
print("ComfyUI 批量图片处理器")
print(f"输入目录: {INPUT_FOLDER}")
print(f"输出目录: {OUTPUT_FOLDER}")
print("="*50)
# 检查文件夹是否存在
if not os.path.isdir(INPUT_FOLDER):
print(f"错误:输入文件夹不存在 {INPUT_FOLDER}")
return
# 确保输出文件夹存在
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
# 加载工作流
try:
with open(WORKFLOW_FILE, 'r', encoding='utf-8') as f:
workflow = json.load(f)
print(f"✅ 成功加载工作流文件: {WORKFLOW_FILE}")
except Exception as e:
print(f"❌ 加载工作流文件失败: {e}")
return
# 获取图片列表
image_files = [
f for f in glob.glob(os.path.join(INPUT_FOLDER, "*.*"))
if f.lower().endswith(IMAGE_EXTENSIONS)
]
if not image_files:
print(f"⚠️ 没有找到支持的图片文件(扩展名: {IMAGE_EXTENSIONS})")
return
print(f"找到 {len(image_files)} 张待处理图片")
# 处理每张图片
success_count = 0
for i, img_path in enumerate(image_files, 1):
img_name = os.path.basename(img_path)
print(f"\n[{i}/{len(image_files)}] 正在处理: {img_name}")
# 检查输出是否已存在
output_exists = any(glob.glob(os.path.join(OUTPUT_FOLDER, f"*{os.path.splitext(img_name)[0]}*")))
if output_exists and not OVERWRITE_EXISTING:
print(f"⏩ 跳过(输出文件已存在)")
continue
# 带重试机制的图片处理
for attempt in range(1, RETRY_TIMES + 1):
try:
# 上传图片
with open(img_path, "rb") as f:
files = {'image': (img_name, f, 'image/png')}
upload_response = requests.post(
f"{COMFYUI_SERVER}/upload/image",
files=files,
timeout=10
)
upload_response.raise_for_status()
# 准备工作流
current_workflow = json.loads(json.dumps(workflow)) # 深拷贝
# 替换图片文件名
for node_id, node in current_workflow.items():
if node.get("class_type") == "LoadImage":
current_workflow[node_id]["inputs"]["image"] = img_name
# 替换自定义参数
for param_name, param_value in CUSTOM_PARAMETERS.items():
for node_id, node in current_workflow.items():
if param_name in node.get("inputs", {}):
current_workflow[node_id]["inputs"][param_name] = param_value
# 提交任务
response = requests.post(
f"{COMFYUI_SERVER}/prompt",
json={"prompt": current_workflow},
timeout=10
)
response.raise_for_status()
prompt_id = response.json()["prompt_id"]
# 等待处理完成
for wait_time in range(TIMEOUT):
time.sleep(1)
history = requests.get(
f"{COMFYUI_SERVER}/history/{prompt_id}",
timeout=10
).json()
if prompt_id in history:
# 保存输出图片
outputs = history[prompt_id].get("outputs", {})
for node_output in outputs.values():
if "images" in node_output:
for img in node_output["images"]:
output_filename = f"{os.path.splitext(img_name)[0]}_{img['filename']}"
output_path = os.path.join(OUTPUT_FOLDER, output_filename)
image_data = requests.get(
f"{COMFYUI_SERVER}/view",
params={
"filename": img["filename"],
"subfolder": img.get("subfolder", ""),
"type": img.get("type", "output")
},
timeout=10
).content
with open(output_path, "wb") as f:
f.write(image_data)
print(f"✅ 保存: {output_filename}")
success_count += 1
break
else:
print(f"⚠️ 处理超时({TIMEOUT}秒)")
continue
break # 处理成功,跳出重试循环
except Exception as e:
print(f"⚠️ 尝试 {attempt}/{RETRY_TIMES} 失败: {str(e)}")
if attempt == RETRY_TIMES:
print(f"❌ 放弃处理: {img_name}")
time.sleep(2)
# 打印摘要
print("\n" + "="*50)
print(f"处理完成!成功 {success_count}/{len(image_files)} 张图片")
print(f"输出目录: {OUTPUT_FOLDER}")
print("="*50)
if __name__ == "__main__":
main()
|