【生成模型】【ComfyUI(三)】使用WebAPI批量调用ComfyUI

news/2025/2/28 9:04:04/

可以参考【生成模型】【ComfyUI(一)】Flux与Flux-Fill部署与API调用中Flux-Fill部分

1. 调整Workflow

我们要部署以下workflow
在这里插入图片描述
做两个修改

  • 输入改为从Load Image(Base64) 读入图片,当然使用上面的从路径中读图也是可以的
  • 输出改为SaveImageWebsocket节点,通过websocket返回图片,当然使用SaveImage给定路径也是可以的
    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d2e2f42f33df4567a63750900590cb75.png

2. 导出API调用json文件

3. 使用接口调用

import requests, websocket
import base64, io
from PIL import Image, ImageColordef buffer2img(imagebuf, mode='RGB', input_type='base64'):if input_type == 'base64':buf = base64.b64decode(imagebuf)elif input_type == 'bytes':buf = imagebufelse:raise ValueError(f"input_type should in ['base64', 'bytes'], but got {input_type}")pil_img = Image.open(io.BytesIO(buf)).convert(mode)return pil_imgdef get_server_address():server_address = "127.0.0.1:8081"return server_addressclass ComfyUIRequest:def __init__(self, progress_bar_node_type=["KSampler"]):self.progress_bar_node_type = progress_bar_node_typedef queue_prompt(self, prompt, client_id, server_address):"""将任务提交给server_address上的ComfyUI,进入处理队列,同时获得返回的trace_id"""p = {"prompt": prompt, "client_id": client_id}# data = json.dumps(p).encode('utf-8')# req =  urllib.request.Request("http://{}/prompt".format(server_address), data=data)# json.loads(urllib.request.urlopen(req).read())response = requests.post(f"http://{server_address}/prompt", json=p)if response.status_code == 200:return response.json()else:logger.error(f"{response}, {response.text}")# print(f"{response}, {response.text}")if response.status_code == 403:# print("get <403>, please check your proxy")logger.error("get <403>, please check your proxy")return Nonedef get_images_from_web_socket(self, prompt, prompt_id, client_id, server_address):ws = websocket.WebSocket()ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id))# progress_bar = ProgressBar(prompt, self.progress_bar_node_type)output_images = {}current_node = ""while True:out = ws.recv()# logger.debug(out, type(out))print(out, type(out))# {"type": "progress", "data": {"value": 49, "max": 50, "prompt_id": "cfd0c1cb-04ae-490d-8ed2-6b16bf103da9", "node": "3"}} <class 'str'># {"type": "progress", "data": {"value": 50, "max": 50, "prompt_id": "cfd0c1cb-04ae-490d-8ed2-6b16bf103da9", "node": "3"}} <class 'str'># {"type": "executing", "data": {"node": "8", "display_node": "8", "prompt_id": "cfd0c1cb-04ae-490d-8ed2-6b16bf103da9"}} <class 'str'>if isinstance(out, str):message = json.loads(out)if message['type'] == 'executing': data = message['data']if 'prompt_id' in data and data['prompt_id'] == prompt_id:if data['node'] is None:break #Execution is doneelse:current_node = data['node']# progress_bar.update(message)else:if current_node in prompt and prompt[current_node]["class_type"] == "SaveImageWebsocket":images_output = output_images.get(current_node, [])images_output.append(out[8:])output_images[current_node] = images_outputreturn output_imagesdef __call__(self, prompt, client_id, server_address):if client_id is None:client_id = str(uuid.uuid4())if server_address is None:server_address = get_server_address()req_data = self.queue_prompt(prompt, client_id, server_address)  # 发起请求if req_data is not None:  # 发起请求成功logger.info(f"req to {req_data}")out_images = self.get_images_from_web_socket(prompt, req_data['prompt_id'], client_id, server_address)  # 阻塞式接受返回return out_imagesreturn Nonecomfyui_reqest = ComfyUIRequest()import jsondefalut_params = json.load(open("05_flux_fill_outpaint_fp8_3.json"))
defalut_params["17"]["inputs"]["image"] = os.path.abspath("524169.jpg")    # input image has mul masked
defalut_params["47"]["inputs"]["image"] = os.path.abspath("524169_mask.jpg")  # mask imageouts = comfyui_reqest(defalut_params, client_id="12347")
result_img = buffer2img(outs['50'][0], input_type='bytes')

print(f"req to {req_data}")打印如下:

req to {'prompt_id': '024d4de7-258b-461c-95fa-a0de3f2fefb0', 'number': 45, 'node_errors': {}}

print(out, type(out))打印如下

{"type": "status", "data": {"status": {"exec_info": {"queue_remaining": 1}}, "sid": "16745628-e6ae-46a9-99a3-fa3a5d53f586"}} <class 'str'>
{"type": "execution_cached", "data": {"nodes": ["7", "23", "26", "31", "32", "34", "38", "39", "55", "56", "57", "58"], "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "timestamp": 1740473304127}} <class 'str'>
{"type": "executed", "data": {"node": "58", "display_node": "58", "output": {"images": [{"filename": "ComfyUI_00022_.png", "subfolder": "", "type": "output"}]}, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722"}} <class 'str'>
{"type": "executed", "data": {"node": "57", "display_node": "57", "output": {"images": [{"filename": "ComfyUI_temp_ukmnl_00001_.png", "subfolder": "", "type": "temp"}]}, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722"}} <class 'str'>
{"type": "executing", "data": {"node": "52", "display_node": "52", "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722"}} <class 'str'>
{"type": "progress", "data": {"value": 1, "max": 20, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "node": "52"}} <class 'str'>
{"type": "progress", "data": {"value": 2, "max": 20, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "node": "52"}} <class 'str'>
{"type": "progress", "data": {"value": 3, "max": 20, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "node": "52"}} <class 'str'>
......
{"type": "progress", "data": {"value": 19, "max": 20, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "node": "52"}} <class 'str'>
{"type": "progress", "data": {"value": 20, "max": 20, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "node": "52"}} <class 'str'>
{"type": "executing", "data": {"node": "8", "display_node": "8", "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722"}} <class 'str'>
{"type": "executing", "data": {"node": "50", "display_node": "50", "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722"}} <class 'str'>
{"type": "progress", "data": {"value": 0, "max": 1, "prompt_id": "eb77c8c4-40d5-4dc0-a6a9-234c25cb4722", "node": "50"}} <class 'str'>

4. 增加调用进度条显示

ComfyUI运行的时候,我们会发现界面上的运行框等信息会变化,这些都是ComfyUI在执行的每个阶段都会发送socket消息,就像上面打印的日志一样,我们可以捕获到这些日志,并增加一些实时的响应。

比如,根据上面日志,增加一个进度条功能,然后解开ComfyUIRequest中与ProgressBar相关的两行代码的注释即可。

from tqdm import tqdmclass ProgressBar(object):def __init__(self, prompt, check_node_types=["KSampler"]):self.prompt = promptself.progress_bars = {}self.check_node_types = check_node_typesdef update(self, message):# {"type": "progress", "data": {"value": 49, "max": 50, "prompt_id": "cfd0c1cb-04ae-490d-8ed2-6b16bf103da9", "node": "3"}} <class 'str'># {"type": "progress", "data": {"value": 50, "max": 50, "prompt_id": "cfd0c1cb-04ae-490d-8ed2-6b16bf103da9", "node": "3"}} <class 'str'># {"type": "executing", "data": {"node": "8", "display_node": "8", "prompt_id": "cfd0c1cb-04ae-490d-8ed2-6b16bf103da9"}} <class 'str'>  try:if message['type'] == 'progress':  # progressnode = message["data"]['node']if node in self.progress_bars:self.progress_bars[node].update(1)else:if node is not None and node in self.prompt and \(self.check_node_types is None or self.prompt[node]["class_type"] in self.check_node_types):max_d, cur_d = message["data"]["max"], message["data"]["value"]bar = self.progress_bars[node] = tqdm(total=max_d, desc=self.prompt[node]["_meta"]["title"])bar.update(1)except KeyboardInterrupt as e:raise eexcept Exception as e:pass

http://www.ppmy.cn/news/1575460.html

相关文章

Flash-03

1-问题&#xff1a;Flash软件画两个图形&#xff0c;若有部分重合则变为一个整体 解决方法1&#xff1a;两个图形分属于不同的图层 解决方法2&#xff1a;将每个图形都转化为【元件】 问题2&#xff1a;元件是什么&#xff1f; 在 Adobe Flash&#xff08;现在称为 Adobe Anim…

Docker迁移/var/lib/docker之后镜像容器丢失问题

迁移/var/lib/docker时&#xff0c;如果目标目录少写一个/&#xff0c;/etc/docker/daemon.json中的data-root后面需要多加一级目录docker。 若迁移命令如下 rsync -avz /var/lib/docker /home/docker/ 在/etc/docker/daemon.json中添加如下内容 "data-root": &q…

栅格地图路径规划:基于雪橇犬优化算法(Sled Dog Optimizer,SDO)的移动机器人路径规划(提供MATLAB代码)

一、雪橇犬优化算法 雪橇犬优化算法&#xff08;Sled Dog Optimizer&#xff0c;SDO&#xff09;是一种于2024年10月发表在JCR1区、中科院1区SCI期刊《Advanced Engineering Informatics》的仿生元启发式算法。它受雪橇犬行为模式启发&#xff0c;通过模拟狗拉雪橇、训练和退役…

ARM Coretex-M核心单片机(STM32)分析hardfault的原因

1. 前提基础知识&#xff08;ARM M核异常 压栈流程&#xff09; M核栈增长方向是地址逐渐减小的&#xff08;TIPS&#xff1a;有的架构的处理器是增大的例如8051内核&#xff0c;而有的像ARM A核心是可设置的 可以增大也可以减小&#xff09; ARM Coretex-M核心常用的有M0 M3 M…

Git Bash:Windows下的强大命令行工具

在Windows系统中&#xff0c;Git提供了Git Bash这一强大的命令行工具&#xff0c;它不仅为开发者提供了一个类Unix的环境&#xff0c;还极大地简化了Git命令的使用。今天&#xff0c;我们就来深入探讨Git Bash的强大功能&#xff0c;并通过实例来展示其在实际开发中的应用。 一…

web网络安全:SQL 注入攻击

SQL 注入攻击&#xff08;SQL Injection&#xff09;概述 SQL 注入&#xff08;SQL Injection&#xff09; 是Web应用程序中最常见的安全漏洞之一。攻击者通过在应用程序的输入字段中插入恶意SQL代码&#xff0c;能够操控数据库执行非预期操作&#xff0c;导致数据泄露、篡改甚…

information_schema.processlist 表详解

information_schema.processlist 表&#xff08;或 SHOW PROCESSLIST; 命令&#xff09;用于查看 MySQL 当前所有的连接进程&#xff0c;帮助管理员监控数据库活动并排查性能问题。以下是该表的字段及其具体含义&#xff1a; &#x1f539; information_schema.processlist 字段…

WINCC 项目初建注意事项

一 新建项目&#xff0c;记得更改存储路径。存C盘不安全&#xff0c;重装系统完犊子。 二 新建画面的分辨率&#xff0c;必须和客户电脑保持一致 三 只要是和颜色相关的&#xff0c;都要关闭“全局颜色方案”&#xff0c;否则更改无效 四 触发器时间更改&#xff0c;否则会…