当前位置: 首页 > news >正文

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

可以参考【生成模型】【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, ImageColor

def buffer2img(imagebuf, mode='RGB', input_type='base64'):
    if input_type == 'base64':
        buf = base64.b64decode(imagebuf)
    elif input_type == 'bytes':
        buf = imagebuf
    else:
        raise ValueError(f"input_type should in ['base64', 'bytes'], but got {input_type}")
    pil_img = Image.open(io.BytesIO(buf)).convert(mode)
    return pil_img

def get_server_address():
    server_address = "127.0.0.1:8081"
    return server_address


class ComfyUIRequest:
    def __init__(self):
        pass

    def 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:
            print(f"{response}, {response.text}")
            return None
    
    def 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))
        
        output_images = {}
        current_node = ""
        while True:
            out = ws.recv()
            print(out, type(out))
            # {"type": "progress", "data": {"value": 0, "max": 1, "prompt_id": "b2f90b54-b022-4993-8042-389455b04134", "node": "50"}} <class 'str'>
            if isinstance(out, str):
                message = json.loads(out)
                # if message['type'] == 'executing':  # progress
                if message['type'] in ['executing', 'progress']:  # progress
                    data = message['data']
                    if 'prompt_id' in data and data['prompt_id'] == prompt_id:
                        if data['node'] is None:
                            break #Execution is done
                        else:
                            current_node = data['node']
            else:
                if prompt[current_node]["class_type"] == "SaveImageWebsocket":
                    images_output = output_images.get(current_node, [])
                    images_output.append(out[8:])
                    output_images[current_node] = images_output
    
        return output_images

    def __call__(self, prompt, client_id, server_address=None):
        if server_address is None:
            server_address = get_server_address()
        req_data = self.queue_prompt(prompt, client_id, server_address)  # 发起请求,任务启动就会返回
        print(f"req to {req_data}")
        prompt_id = req_data['prompt_id']
        out_images = self.get_images_from_web_socket(prompt, prompt_id, client_id, server_address)  # 阻塞式接受返回
        return out_images


comfyui_reqest = ComfyUIRequest()

import json

defalut_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 image

outs = 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'>

相关文章:

  • Linux发展史、发行版本、特性以及应用场景
  • Revisiting Reverse Distillation for Anomaly Detection
  • 在CentOS7上部署与关闭Flask接口
  • 视频孪生技术赋能文旅数字化转型:重构景区体验与管理新模式
  • 嵌入式开发:傅里叶变换(5):STM32和Matlab联调验证FFT
  • MobSF(Mobile Security Framework) 的详细介绍、安装指南、配置说明
  • 物联网平台建设方案一
  • 力扣提升第一天
  • 在linux中利用conda安装blast
  • openssh9.9p2部分Linux操作系统的rpm包
  • Spring boot中的@ConfigurationProperties注解
  • 完全背包问题
  • SQL注入(order by,limit),seacms的报错注入以及系统库的绕过
  • deepseek部署:ELK + Filebeat + Zookeeper + Kafka
  • [C++][cmake]使用C++部署yolov12目标检测的tensorrt模型支持图片视频推理windows测试通过
  • LUCEDA IPKISS Tutorial 81:通过参数函数定义形状
  • Spring Cloud源码 - Eureka源码原理分析
  • 17142弹珠堆放
  • ROS的action通信——实现阶乘运算(三)
  • echarts记录(柱状、折线、环形饼图,双柱,日期组件封装)
  • 如何自制公司网站/登录百度账号注册
  • 在做博彩的公司做网站运营犯法吗/合肥网站优化排名推广
  • 有没有教做蛋糕的网站/热门关键词排名查询
  • 万网主机 wordpress/关键词优化好
  • jsp网站开发实例实验报告/如何制作网页设计
  • 什么网站做兼职最好/百度网页