## 注意
- KSampler或其他有randomize產出的 seed 要記得換,結果才會不一樣
## 將workflow用api呼叫
1. 開啟ComfyUI的Dev Mode


2. 以API格式下載workflow

3. 以[換臉workflow(點擊跳轉至json檔)](#換臉workflow)為例
1. 使用`POST /upload/image`上傳需要的圖檔
2. 將response.json['name']的檔名分別放入workflow中兩個LoadImage節點的輸入
- target: workflow['nodes'][0]['widgets_values'][0]
- source: workflow['nodes'][1]['widgets_values'][0]
3. 根據需求,調整workflow中ReActorFaceSwap或SaveImage節點的輸入,所需輸入可透過以下API查看
- ReActorFaceSwap: /object_info/ReActorFaceSwap
- SaveImage: /object_info/SaveImage
4. 使用`POST /prompt`開始執行workflow,body中需包含一個用於追蹤的client_id(自訂)和prompt(workflow)
```json
{
"client_id": "TESTING",
"prompt": {
...
}
}
```
5. 使用`WS /ws?clientId=TESTING`追蹤執行進度
1. 接上時收到佇列中的任務數
2. 收到type="execution_start"的訊息,代表該clientId送出的prompt被執行
3. 進入下一個工作節點時,會收到type="executing"的訊息
4. 收到type="executed"的訊息,代表執行完畢
- 輸出檔名: message['data']['output']['images'][0]['filename']
- 輸出類型: message['data']['output']['images'][0]['filename']
6. 將5-4的filename和type作為參數,使用`GET /view?filename=xxx&type=xxx`取得輸出圖像
## workflows
### 換臉workflow
```jsonld=
{
"last_node_id": 4,
"last_link_id": 3,
"nodes": [
{
"id": 3,
"type": "LoadImage",
"pos": [
34,
-127
],
"size": {
"0": 315,
"1": 314
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
2
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"target.jpg",
"image"
]
},
{
"id": 2,
"type": "LoadImage",
"pos": [
35,
248
],
"size": [
315,
314.00000381469727
],
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
1
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"source.jpg",
"image"
]
},
{
"id": 1,
"type": "ReActorFaceSwap",
"pos": [
422,
50
],
"size": {
"0": 315,
"1": 338
},
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "input_image",
"type": "IMAGE",
"link": 2
},
{
"name": "source_image",
"type": "IMAGE",
"link": 1
},
{
"name": "face_model",
"type": "FACE_MODEL",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
3
],
"shape": 3,
"slot_index": 0
},
{
"name": "FACE_MODEL",
"type": "FACE_MODEL",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "ReActorFaceSwap"
},
"widgets_values": [
true,
"inswapper_128.onnx",
"retinaface_resnet50",
"none",
1,
0.5,
"no",
"no",
"0",
"0",
1
]
},
{
"id": 4,
"type": "SaveImage",
"pos": [
780,
61
],
"size": {
"0": 315,
"1": 58
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 3
}
],
"properties": {},
"widgets_values": [
"ComfyUI"
]
}
],
"links": [
[
1,
2,
0,
1,
1,
"IMAGE"
],
[
2,
3,
0,
1,
0,
"IMAGE"
],
[
3,
1,
0,
4,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
```
## ComfyUI WebSocket訊息
|type|data|
|-|-|
|訊息類型|實際資訊|
### meaning and data of each type
#### status
- 連線建立
```json
{
"status": {
"exec_info": {
"queue_remaining": 2 // total prompts executing or waiting for execution
}
},
"sid": "testing" //clientID of this connection
}
```
- queue有更新的通知訊息
```json
{
"status": {
"exec_info": {
"queue_remaining": 2 // total prompts executing or waiting for execution
}
}
}
```
#### execution_start
- 開始執行由此clientID請求執行的prompt
```json
{
"prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt
}
```
#### execution_cached
- 上一個執行的prompt中,有某些output nodes的結果並未變化,使用cache可以減少節省執行的時間
```json
{
"nodes": ["1", "2", "3"], // id of output nodes that can use cached result
"prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt
}
```
#### executing
- 目前執行的節點
```json
{
"node": "1", // id of the executing prompt
"prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt
}
```
- 執行完畢
```json
{
"node": null,
"prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt
}
```
#### progress
- 節點內部的執行進度
```json
{
"value": 1, // current round
"max": 20, // total rounds
"node": "1", // id of the executing prompt
"prompt_id": "ef8136ac-4c7a-4181-aaec-2f75ae26ee11" // id of the executing prompt
}
```
## API文件
[postman範例](https://www.postman.com/dark-firefly-849863/workspace/comfyui)
## 可能遇到的問題
### 找不到節點
- [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager)
### 找不到模型
- ~~[Install missing nodes and models](https://github.com/piyushK52/comfy_runner)~~: 執行時會再安裝另一套ComfyUI,不怎麼好(2024/05/27)
## 參考文件
[API documentation](https://gitee.com/BTYY/wailikeji-chatgpt/blob/master/comfyui-api.md)
[簡體中文教程](https://blog.csdn.net/jjs15259655776/article/details/134388940)
[comfyui-api](https://github.com/9elements/comfyui-api)