Compare commits

46 Commits
Author SHA1 Message Date
Your Name a027ad12aa save code 2026-03-12 02:40:26 +00:00
Your Name e5aa87bf1c save code 2026-03-10 08:42:23 +00:00
Your Name adb79e5614 add proxy 2026-03-10 08:07:17 +00:00
Your Name 6d4d2c19b3 save code 2026-03-10 07:10:36 +00:00
Your Name 01fa717f5f save code 2026-03-08 16:02:37 +00:00
xsl 339e7dc1f6 save code 2026-02-27 22:56:59 +08:00
xsl 73e356def7 根据图片是否有人脸,判断衣服长度 2025-11-02 13:43:39 +08:00
xsl 4a0a78e128 添加衣服长度字段 2025-11-02 00:12:58 +08:00
xsl b1a291f6eb save code 2025-11-01 23:14:28 +08:00
xsl 711cfd1502 save code 2025-10-08 14:36:05 +08:00
xsl 341f81333b save code 2025-10-08 00:16:50 +08:00
xsl ab2f86d04f nano banana success 2025-10-06 21:40:03 +08:00
xsl 71ec26c7de save code 2025-10-04 17:14:04 +08:00
xsl 1fbb91eadb save code 2025-10-04 12:53:01 +08:00
xsl 20e6b294f1 save code 2025-10-02 16:47:05 +08:00
xsl af30bcc97c save code 2025-09-09 11:36:17 +08:00
xsl 09a57cdac3 save 2025-08-26 23:22:59 +08:00
xsl cd15cc0308 save code 2025-08-26 20:42:28 +08:00
xsl fe3b9db57d save code 2025-08-26 20:30:00 +08:00
xsl ca2f1e31bc save code 2025-08-19 21:45:35 +08:00
xsl a0fb6b37e9 save code 2025-08-18 22:46:06 +08:00
xsl 6fd1c9feb9 save code 2025-08-18 21:54:20 +08:00
xsl 06db1ba02b save code 2025-08-18 21:36:17 +08:00
xsl 10e2dec267 save code 2025-08-18 21:26:37 +08:00
xsl bd39f2e425 save code 2025-08-18 20:58:55 +08:00
xsl f420e8b86c save code 2025-08-14 10:45:10 +08:00
colomi 261e44eabb save code 2025-08-13 22:43:41 +08:00
xsl 39814fe1c6 save code 2025-08-13 22:20:10 +08:00
xsl 82842d1b5c save code 2025-08-13 21:07:25 +08:00
xsl 59d132389d Merge branch '5090' of http://43.143.205.217:3000/xsl/change_cloth into 5090 2025-08-13 21:06:43 +08:00
xsl 2536be8828 save code 2025-08-13 21:05:28 +08:00
xsl 5290fc974a asdf 2025-08-12 22:38:40 +08:00
xsl ea55aaa0eb save code 2025-08-11 22:25:50 +08:00
xsl 9a28b272aa save code 2025-08-10 23:54:29 +08:00
xsl 7ac1bdde41 save code 2025-08-10 23:13:32 +08:00
xsl 8b55a66079 save code 2025-08-10 23:07:52 +08:00
xsl 30c624e5af save code 2025-08-10 20:55:26 +08:00
xsl 742974a786 save code 2025-08-10 20:53:46 +08:00
xsl 7a08f7eca8 save code 2025-08-10 20:37:27 +08:00
xsl 9dad88f8be save code 2025-08-10 14:11:34 +08:00
xsl 276066cabb save code 2025-08-09 23:34:32 +08:00
xsl 1104fb54d9 save code 2025-08-09 22:32:20 +08:00
xsl 4784464a5f save code 2025-08-09 22:23:23 +08:00
xsl b92fd5e782 save code 2025-08-09 21:41:35 +08:00
xsl a592c4a552 save code 2025-08-09 14:48:13 +08:00
xsl b9f85fc0df save code 2025-07-31 11:22:40 +08:00
67 changed files with 10355 additions and 166 deletions
+108
View File
@@ -0,0 +1,108 @@
# change_app.py API 文档
## 1. GET /
返回主页静态文件 `index.html`
---
## 2. POST /change_cloth
**推荐入口**,带 Redis 队列排队,避免并发冲突。
### 请求参数(JSON
| 参数 | 类型 | 必选 | 说明 |
|------|------|------|------|
| human_url | string | 是 | 人物图片 URL |
| cloth_url | string | 是 | 服装图片 URL |
| output_format | string | 是 | 输出格式,包含 `"base64"` 则返回 base64,否则返回 URL |
| no2 | bool | 否 | true=跳过第一步(脱衣/生成写真),直接换衣;默认 false |
| tuodi | bool | 否 | true=使用拖地款工作流;默认 false |
| kuzi | bool | 否 | 是否同时换裤子(配合 kuzi_url);默认 false |
| cloth_len | string | 否 | 手动指定服装长度(如"膝盖""拖地"等),不传则 AI 自动判断 |
| suit | bool | 否 | true=使用 Gemini 模型换装(套装模式);默认 false |
### 响应
```json
// 成功(URL 模式)
{
"ret": 0,
"state": 0,
"msg": "success",
"url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/xxx.jpg",
"second_url": "换衣前中间步骤图 URL",
"first_url": "第一步(脱衣/写真)图 URL",
"is_girl": true
}
// 成功(base64 模式)
{
"ret": 0,
"state": 0,
"msg": "success",
"data": "data:image/jpeg;base64,...",
"second_step_data": "...",
"first_step_data": "...",
"is_girl": true
}
// 失败
{ "ret": -1, "state": -1, "msg": "错误信息" }
```
---
## 3. POST /change_cloth_base64
`/change_cloth` 功能相同,图片以 Base64 格式传入。
### 请求参数(JSON
| 参数 | 类型 | 必选 | 说明 |
|------|------|------|------|
| human_img | string | 是 | 人物图片 base64(带 data: 头,如 `data:image/jpeg;base64,...` |
| cloth_img | string | 是 | 服装图片 base64 |
| output_format | string | 是 | 同上 |
| kuzi_img | string | 否 | 裤子图片 base64 |
| no2 | bool | 否 | 同上 |
| tuodi | bool | 否 | 同上 |
| suit | bool | 否 | 同上 |
| cloth_len | string | 否 | 同上 |
### 响应
`/change_cloth`
---
## 4. POST /do_change_cloth
**直接调用**,无队列保护,通常由内部或 `/change_cloth_base64` 调用,不建议外部直接使用。
### 请求参数(JSON
| 参数 | 类型 | 必选 | 说明 |
|------|------|------|------|
| human_url | string | 是 | 人物图片 URL |
| cloth_url | string | 是 | 服装图片 URL |
| output_format | string | 是 | 同上 |
| no2 | bool | 否 | 同上 |
| tuodi | bool | 否 | 同上 |
| kuzi_url | string | 否 | 裤子图片 URL |
| cloth_len | string | 否 | 同上 |
| suit | bool | 否 | 同上 |
### 响应
`/change_cloth`
---
## 备注
- `cloth_len` 可选值:`胸、腰、跨、大腿、膝盖、小腿、脚踝、拖地、裤子、难以辨认`
- 若服装图片中检测到人物,`cloth_len` 自动设为 `拖地`
- 结果图片同时上传至阿里云 OSS(bucket: `xiangsilian`region: 北京)
- 服务默认监听端口由 `config.py` 中的 `base64_test_port` 决定
+34 -35
View File
@@ -1,42 +1,41 @@
import json # -*- coding=utf-8
from urllib import request from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
import sys
import os
import logging
#This is the ComfyUI api prompt format. # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
#If you want it for a specific workflow you can "enable dev mode options" # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
#in the settings of the UI (gear beside the "Queue Size: ") this will enable secret_id = 'AKIDDIBrNhoiOtBF5rcEdoBRUKwU2Rj2OgxA' # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
#a button on the UI to save workflows in api format. secret_key = '5wkKhttgYQD2iEZgaInEVYVPCo2BJK9l' # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
region = 'ap-beijing' #'ap-guangzhou' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
#keep in mind ComfyUI is pre alpha software so this format will change a bit. # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224
token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
#this is the one for the default workflow scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填
def queue_prompt(prompt):
p = {"prompt": prompt}
# If the workflow contains API nodes, you can add a Comfy API key to the `extra_data`` field of the payload.
# p["extra_data"] = {
# "api_key_comfy_org": "comfyui-87d01e28d*******************************************************" # replace with real key
# }
# See: https://docs.comfy.org/tutorials/api-nodes/overview
# Generate a key here: https://platform.comfy.org/login
data = json.dumps(p).encode('utf-8')
req = request.Request("http://127.0.0.1:8188/prompt", data=data)
request.urlopen(req)
with open('/home/szlc/code/ComfyUI/change_cloth/basic_api.json', 'r', encoding='utf-8') as file: config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
prompt_text = file.read() client = CosS3Client(config)
prompt = json.loads(prompt_text) #### 文件流简单上传(不支持超过5G的文件,推荐使用下方高级上传接口)
#set the text prompt for our positive CLIPTextEncode # 强烈建议您以二进制模式(binary mode)打开文件,否则可能会导致错误
prompt["6"]["inputs"]["text"] = "masterpiece best quality man" with open('out_image.png', 'rb') as fp:
response = client.put_object(
#set the seed for our KSampler node Bucket='b-1304254135',
prompt["3"]["inputs"]["seed"] = 5 Body=fp,
Key='out_image.png',
StorageClass='STANDARD',
queue_prompt(prompt) EnableMD5=False
)
print(response['ETag'])
#### 获取文件到本地
response = client.get_object(
Bucket='b-1304254135',
Key='out_image.png'
)
response['Body'].get_stream_to_file('cos_girl.png')
+440 -73
View File
@@ -1,7 +1,7 @@
import os import os
import uuid import uuid
import requests import requests
from flask import Flask, request, jsonify from flask import Flask, request, jsonify, Response
from urllib.parse import urlparse from urllib.parse import urlparse
import json import json
import base64 import base64
@@ -14,7 +14,11 @@ import oss2
import redis import redis
# from check_img_body import is_thigh_visible # from check_img_body import is_thigh_visible
import logging import logging
from config import QUEUE_NAME, DEFAULT_TIMEOUT, KEY_QUEUE_LOCK_NAME, acquire_lock from config import *
import websockets
import asyncio
import traceback
import re
APP_ROOT = os.path.dirname(os.path.abspath(__file__)) APP_ROOT = os.path.dirname(os.path.abspath(__file__))
@@ -28,7 +32,7 @@ logger.setLevel(logging.INFO) # 设置 logger 的级别
now = datetime.now() now = datetime.now()
# 格式化为字符串(例如:2023-10-25 14:30:45 # 格式化为字符串(例如:2023-10-25 14:30:45
date_time_str = now.strftime("%Y-%m-%d_%H:%M:%S") date_time_str = now.strftime("%Y-%m-%d_%H-%M-%S")
# 创建文件 handler # 创建文件 handler
file_handler = logging.FileHandler(f'/var/log/fuyan/change_app_{date_time_str}.log') file_handler = logging.FileHandler(f'/var/log/fuyan/change_app_{date_time_str}.log')
@@ -58,11 +62,19 @@ redis_pool = redis.ConnectionPool(
max_connections=2000 # 根据实际情况调整 max_connections=2000 # 根据实际情况调整
) )
from datetime import datetime
def log_message(msg):
"""简单的日志输出函数"""
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {msg}")
logger.info(msg)
def get_redis_conn(): def get_redis_conn():
"""获取 Redis 连接""" """获取 Redis 连接"""
return redis.Redis(connection_pool=redis_pool) return redis.Redis(connection_pool=redis_pool)
app = Flask(__name__) app = Flask(__name__, static_folder='static', static_url_path='/static')
from flask_cors import CORS
CORS(app)
client = Ark( client = Ark(
# 此为默认路径,您可根据业务所在地域进行配置 # 此为默认路径,您可根据业务所在地域进行配置
@@ -97,6 +109,32 @@ def GetPicDesc(img_url):
print(text) print(text)
return text return text
def GetPicHumanFace(img_url):
response = client.chat.completions.create(
# 指定您创建的方舟推理接入点 ID,此处已帮您修改为您的推理接入点 ID
model="doubao-1.5-vision-pro-250328",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": img_url
},
},
{"type": "text", "text": "图片是一件有服装的照片,帮忙分析一下,返回为json格式, 字段名是'face_state', 图片是否有人脸或者人,有人或者人穿着衣服就返回'有人' 没有就返回'没人'"},
],
}
],
)
text = response.choices[0].message.content
print(text)
return text
def GetHumanDesDesc(img_url): def GetHumanDesDesc(img_url):
response = client.chat.completions.create( response = client.chat.completions.create(
# 指定您创建的方舟推理接入点 ID,此处已帮您修改为您的推理接入点 ID # 指定您创建的方舟推理接入点 ID,此处已帮您修改为您的推理接入点 ID
@@ -123,12 +161,12 @@ def GetHumanDesDesc(img_url):
return text return text
def takeoff_cloth_first(human_name, is_girl): def takeoff_cloth_first(human_name, is_girl):
print('换泳装') print(f'换泳装 {change_with_add_cloth}')
queue = requests.get("http://localhost:8188/queue").json() queue = requests.get("http://localhost:8188/queue").json()
if queue["queue_running"] or queue["queue_pending"]: if queue["queue_running"] or queue["queue_pending"]:
return None, "cur gpu is busy" return None, "cur gpu is busy"
with open('/home/szlc/code/ComfyUI/change_cloth/change_new.json', 'r', encoding='utf-8') as file: with open(f'{APP_ROOT}/{change_with_add_cloth}', 'r', encoding='utf-8') as file:
prompt_text = file.read() prompt_text = file.read()
prompt = json.loads(prompt_text) prompt = json.loads(prompt_text)
@@ -140,9 +178,10 @@ def takeoff_cloth_first(human_name, is_girl):
#input cloth img #input cloth img
if is_girl: if is_girl:
prompt["22"]["inputs"]["image"] = 'girl_cloth.jpg' prompt["22"]["inputs"]["image"] = 'girl_cloth_new_new.png'
else: else:
prompt["22"]["inputs"]["image"] = 'man_cloth.jpg' prompt["22"]["inputs"]["image"] = 'man_cloth_grey.jpg'
# prompt["22"]["inputs"]["image"] = 'man_cloth.jpg'
#input human img #input human img
prompt["61"]["inputs"]["image"] = human_name prompt["61"]["inputs"]["image"] = human_name
@@ -181,12 +220,12 @@ def takeoff_cloth_first(human_name, is_girl):
return None return None
def generate_from_face(human_name, sex_girl): def generate_from_face(human_name, sex_girl):
print('生成写真') print(f'生成写真 {xiezhen_name}')
queue = requests.get("http://localhost:8188/queue").json() queue = requests.get("http://localhost:8188/queue").json()
if queue["queue_running"] or queue["queue_pending"]: if queue["queue_running"] or queue["queue_pending"]:
return None, "cur gpu is busy" return None, "cur gpu is busy"
with open('/home/szlc/code/ComfyUI/change_cloth/xiezhen_girl.json', 'r', encoding='utf-8') as file: with open(f'{APP_ROOT}/{xiezhen_name}', 'r', encoding='utf-8') as file:
prompt_text = file.read() prompt_text = file.read()
prompt = json.loads(prompt_text) prompt = json.loads(prompt_text)
@@ -194,10 +233,16 @@ def generate_from_face(human_name, sex_girl):
prompt["93"]["inputs"]["image"] = human_name prompt["93"]["inputs"]["image"] = human_name
# if sex_girl:
# prompt["6"]["inputs"]["text"] = "asian girl,knee-length shot ,model pose,hands are at the sides of the body,smile,wearing black tube top and micro skirt,simple ,white background,32k,high detail,and face is illuminated by soft side light and natural light. The sunlight spills over the white wall behind."
# else:
# prompt["6"]["inputs"]["text"] = "asian man,tall,knee-length shot,model pose,hands are at the sides of the body,smile,wearing black short pants,simple white background,The sunlight spills over the white wall behind,32k."
if sex_girl: if sex_girl:
prompt["6"]["inputs"]["text"] = "asian girl,full body shot(1.9),complete figure,front-facing,model pose,hands are at the sides of the body,smile,wearing black tube top and micro skirt,simple ,white background,32k,high detail,and face is illuminated by soft side light and natural light. The sunlight spills over the white wall behind." prompt["6"]["inputs"]["text"] = "asian girl,knee-length shot,model pose,hands are at the sides of the body,smile,wearing black tube top and micro skirt,solid very dark gray background,32k,high detail,and face is illuminated by soft side light and natural light."
else: else:
prompt["6"]["inputs"]["text"] = "asian man,full body shot(1.9),complete figure,front-facing,model pose,hands are at the sides of the body,smile,wearing black tight shortst,simple white background,32k,high detail,and face is illuminated by soft side light and natural light. The sunlight spills over the white wall behind." prompt["6"]["inputs"]["text"] = "asian man,tall,knee-length shot,model pose,hands are at the sides of the body,smile,shirtless,wearing black short pants,very dark gray background,solid dark gray background,32k,"
#out put name #out put name
out_img_name = str(uuid.uuid4())[:8] out_img_name = str(uuid.uuid4())[:8]
@@ -232,7 +277,7 @@ def generate_from_face(human_name, sex_girl):
return out_img_file_name return out_img_file_name
return None return None
def change(human_name, cloth_name, c_width, c_height, cloth_url, human_url, no2): def change(human_name, cloth_name, c_width, c_height, cloth_url, human_url, no2, tuodi, cloth_len):
human_json_str = GetHumanDesDesc(human_url) human_json_str = GetHumanDesDesc(human_url)
print(f"human_json_str {human_json_str}") print(f"human_json_str {human_json_str}")
human_json_data = json.loads(human_json_str) human_json_data = json.loads(human_json_str)
@@ -243,29 +288,44 @@ def change(human_name, cloth_name, c_width, c_height, cloth_url, human_url, no2)
sgwzd = human_json_data['身高完整度'] sgwzd = human_json_data['身高完整度']
json_str = GetPicDesc(cloth_url)
json_data = json.loads(json_str)
cloth_len = json_data['服装长度']
cloth_short = True cloth_short = True
if '长袖' in json_data['衣袖']: if cloth_len == None:
cloth_short = False json_str = GetPicDesc(cloth_url)
if cloth_len == '难以辨认': print(f"GetPicDesc:{json_str}")
return None, None, sex_girl, "get image type error" json_data = json.loads(json_str)
cloth_len = json_data['服装长度']
if '长袖' in json_data['衣袖']:
cloth_short = False
else:
print(f'change 函数里面获取的 cloth_len')
cloth_json_str = GetPicHumanFace(cloth_url)
print(f"cloth_json_str:{cloth_json_str}")
cloth_json_data = json.loads(cloth_json_str)
if cloth_json_data['face_state'] == '有人':
cloth_len = '拖地'
print(f"tuodi:{tuodi}")
if tuodi == True or tuodi == "true":
cloth_len = '拖地'
if no2 == True: if no2 == True:
print(f'不用第二部 no2{no2}') print(f'不用第二部 no2{no2}')
else: else:
print(f'要第二部 no2{no2} 先搞第一步') print(f'要第二部 no2{no2} 先搞第一步')
# thigh_visible = is_thigh_visible(f"/home/szlc/code/ComfyUI/input/{human_name}") if sgwzd >= 0.70:
if sgwzd >= 0.5:
#脱衣服 #脱衣服
takeoff_file_name = takeoff_cloth_first(human_name, sex_girl) takeoff_file_name = takeoff_cloth_first(human_name, sex_girl)
print(f"takeoff_file_name:{takeoff_file_name} human_name:{human_name} sex_girl:{sex_girl}")
if takeoff_file_name == None: if takeoff_file_name == None:
return None, None, sex_girl, f"takeoff_cloth_first error {human_name}" return None, None, sex_girl, f"takeoff_cloth_first error {human_name}"
else: else:
human_name = takeoff_file_name human_name = takeoff_file_name
takeoff_file_path_name = os.path.join('/home/szlc/code/ComfyUI/output', takeoff_file_name) takeoff_file_path_name = os.path.join(f'{APP_ROOT}/../output', takeoff_file_name)
takeoff_file_path_name_input = os.path.join('/home/szlc/code/ComfyUI/input', takeoff_file_name) takeoff_file_path_name_input = os.path.join(f'{APP_ROOT}/../input', takeoff_file_name)
shutil.copy(takeoff_file_path_name, takeoff_file_path_name_input) shutil.copy(takeoff_file_path_name, takeoff_file_path_name_input)
else: else:
#生成写真 #生成写真
@@ -274,17 +334,22 @@ def change(human_name, cloth_name, c_width, c_height, cloth_url, human_url, no2)
return None, None, sex_girl, f"xiezhen error {human_name}" return None, None, sex_girl, f"xiezhen error {human_name}"
else: else:
human_name = generate_name human_name = generate_name
generate_name_file_path_name = os.path.join('/home/szlc/code/ComfyUI/output', generate_name) generate_name_file_path_name = os.path.join(f'{APP_ROOT}/../output', generate_name)
generate_name_file_path_name_input = os.path.join('/home/szlc/code/ComfyUI/input', generate_name) generate_name_file_path_name_input = os.path.join(f'{APP_ROOT}/../input', generate_name)
shutil.copy(generate_name_file_path_name, generate_name_file_path_name_input) shutil.copy(generate_name_file_path_name, generate_name_file_path_name_input)
queue = requests.get("http://localhost:8188/queue").json() queue = requests.get("http://localhost:8188/queue").json()
if queue["queue_running"] or queue["queue_pending"]: if queue["queue_running"] or queue["queue_pending"]:
return None, None, sex_girl, "cur gpu is busy, Shou not happen" return None, None, sex_girl, "cur gpu is busy, Shou not happen"
print('开始换衣服') if tuodi:
with open('/home/szlc/code/ComfyUI/change_cloth/change_new.json', 'r', encoding='utf-8') as file: print(f'开始换衣服 {change_tuodi_input} cloth_len:{cloth_len} cloth_short:{cloth_short}')
prompt_text = file.read() with open(f'{APP_ROOT}/{change_tuodi_input}', 'r', encoding='utf-8') as file:
prompt_text = file.read()
else:
print(f'开始换衣服 {change_only_name} cloth_len:{cloth_len} cloth_short:{cloth_short}')
with open(f'{APP_ROOT}/{change_only_name}', 'r', encoding='utf-8') as file:
prompt_text = file.read()
prompt = json.loads(prompt_text) prompt = json.loads(prompt_text)
@@ -310,9 +375,8 @@ def change(human_name, cloth_name, c_width, c_height, cloth_url, human_url, no2)
response = requests.post("http://localhost:8188/prompt", data=data) response = requests.post("http://localhost:8188/prompt", data=data)
prompt_id = response.json()["prompt_id"] prompt_id = response.json()["prompt_id"]
# 2. 轮询队列,直到任务完成
while True: while True:
# response = requests.post("http://localhost:8188/interrupt")
queue = requests.get("http://localhost:8188/queue").json() queue = requests.get("http://localhost:8188/queue").json()
# print(queue) # print(queue)
if not queue["queue_running"] and not queue["queue_pending"]: if not queue["queue_running"] and not queue["queue_pending"]:
@@ -332,6 +396,61 @@ def change(human_name, cloth_name, c_width, c_height, cloth_url, human_url, no2)
return out_img_file_name, human_name, sex_girl,"success" return out_img_file_name, human_name, sex_girl,"success"
return None, human_name, sex_girl, "can not find output image" return None, human_name, sex_girl, "can not find output image"
def change_kuzi(human_name, kuzi_name):
queue = requests.get("http://localhost:8188/queue").json()
if queue["queue_running"] or queue["queue_pending"]:
return None, "cur gpu is busy, Shou not happen"
print(f'开始换裤子 {change_only_name}')
with open(f'{APP_ROOT}/{change_only_name}', 'r', encoding='utf-8') as file:
prompt_text = file.read()
prompt = json.loads(prompt_text)
prompt["96"]["inputs"]["cloth_len"] = "裤子"
prompt["96"]["inputs"]["cloth_short"] = False
# prompt["99"]["inputs"]["width"] = int((c_width/c_height) * 1024)
#input cloth img
prompt["22"]["inputs"]["image"] = kuzi_name
#input human img
prompt["61"]["inputs"]["image"] = human_name
#out put name
out_img_name = str(uuid.uuid4())[:8]
prompt["102"]["inputs"]["filename_prefix"] = out_img_name
p = {"prompt": prompt}
data = json.dumps(p).encode('utf-8')
response = requests.post("http://localhost:8188/prompt", data=data)
prompt_id = response.json()["prompt_id"]
while True:
# response = requests.post("http://localhost:8188/interrupt")
queue = requests.get("http://localhost:8188/queue").json()
# print(queue)
if not queue["queue_running"] and not queue["queue_pending"]:
break # 队列为空,任务已完成
time.sleep(0.5) # 避免频繁请求
# 3. 从历史记录中获取结果
history = requests.get("http://localhost:8188/history").json()
# print("History:", history)
outputs = history[prompt_id]["outputs"]
for out in outputs:
if 'images' in outputs[out]:
for out_img in outputs[out]['images']:
if 'filename' in out_img:
out_img_file_name = out_img['filename']
if out_img_name in out_img_file_name:
return out_img_file_name,"success"
return None, "can not find output image"
def save_base64_image(base64_str, prefix): def save_base64_image(base64_str, prefix):
""" """
将base64字符串保存为图片文件 将base64字符串保存为图片文件
@@ -360,13 +479,13 @@ def save_base64_image(base64_str, prefix):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
unique_id = str(uuid.uuid4())[:8] unique_id = str(uuid.uuid4())[:8]
filename = f"{prefix}_{timestamp}_{unique_id}{file_ext}" filename = f"{prefix}_{timestamp}_{unique_id}{file_ext}"
filepath = os.path.join('/home/szlc/code/ComfyUI/change_cloth/static/imgs', filename) filepath = os.path.join(f'{APP_ROOT}/static/imgs', filename)
# 解码并保存图片 # 解码并保存图片
with open(filepath, 'wb') as f: with open(filepath, 'wb') as f:
f.write(base64.b64decode(data)) f.write(base64.b64decode(data))
input_filepath = os.path.join('/home/szlc/code/ComfyUI/input', filename) input_filepath = os.path.join(f'{APP_ROOT}/../input', filename)
# 解码并保存图片 # 解码并保存图片
with open(input_filepath, 'wb') as f: with open(input_filepath, 'wb') as f:
f.write(base64.b64decode(data)) f.write(base64.b64decode(data))
@@ -386,32 +505,32 @@ def get_image_dimensions(image_path):
print(f"Error: {e}") print(f"Error: {e}")
return None return None
def image_to_base64(file_path, mime_type=None): def image_to_base64(file_path, with_head = True):
if mime_type is None: extension = file_path.split('.')[-1].lower()
extension = file_path.split('.')[-1].lower() mime_types = {
mime_types = { 'jpg': 'image/jpeg',
'jpg': 'image/jpeg', 'jpeg': 'image/jpeg',
'jpeg': 'image/jpeg', 'png': 'image/png',
'png': 'image/png', 'gif': 'image/gif',
'gif': 'image/gif', 'webp': 'image/webp',
'webp': 'image/webp', 'bmp': 'image/bmp'
'bmp': 'image/bmp' }
} mime_type = mime_types.get(extension, 'application/octet-stream')
mime_type = mime_types.get(extension, 'application/octet-stream')
# 读取文件内容并编码为Base64
with open(file_path, 'rb') as image_file: with open(file_path, 'rb') as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8') encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
# 组合成Data URI格式 if with_head:
return f"data:{mime_type};base64,{encoded_string}" return f"data:{mime_type};base64,{encoded_string}"
else:
return encoded_string
def upload_to_oss(image_path, object_name=None): def upload_to_oss(image_path, object_name=None):
# 配置信息(替换为你的实际信息) # 配置信息(替换为你的实际信息)
access_key_id = 'LTAI5tB9t2RH6f1drSLvVLLZ' access_key_id = 'LTAI5tGp1sLzedqxihcNC1eb'
access_key_secret = '91uzPI1RAFHN7n3Y6TJDGFP8w0dG1R' access_key_secret = 'IFZE1b8YYreCP6zfA6GaZ9uBT678qO'
endpoint = 'oss-cn-beijing.aliyuncs.com' # 替换为你的Endpoint endpoint = 'oss-cn-beijing.aliyuncs.com' # 替换为你的Endpoint
bucket_name = 'llyz' bucket_name = 'xiangsilian'
# 创建Bucket实例 # 创建Bucket实例
auth = oss2.Auth(access_key_id, access_key_secret) auth = oss2.Auth(access_key_id, access_key_secret)
@@ -437,11 +556,159 @@ def upload_to_oss(image_path, object_name=None):
print(f"上传失败: {str(e)}") print(f"上传失败: {str(e)}")
return None return None
def get_image_from_json(json_str):
try:
data = json.loads(json_str)
parts = data["candidates"][0]["content"]["parts"]
base64_data = None
for part in parts:
if "inlineData" in part and "data" in part["inlineData"]:
base64_data = part["inlineData"]["data"]
break
def process_change_cloth(human_filename, cloth_filename, output_format, img_url, human_url, no2): if base64_data is None:
w,h = get_image_dimensions(f'/home/szlc/code/ComfyUI/input/{human_filename}') print("未找到包含图片数据的部分")
return None
out_put_name, out_human_name, is_girl, msg = change(human_filename, cloth_filename, w, h, img_url, human_url, no2) base64_data = re.sub(r'\s+', '', base64_data)
image_data = base64.b64decode(base64_data)
return image_data
except Exception as e:
print(f"保存图片时发生错误: {e}")
return None
import http.client
from io import BytesIO
def process_change_banana(human_filename, cloth_filename, output_format):
human_filepath = os.path.join(f'{APP_ROOT}/../input', human_filename)
suit_filepath = os.path.join(f'{APP_ROOT}/../input', cloth_filename)
conn = http.client.HTTPSConnection("ai.juguang.chat")
payload = json.dumps({
"contents": [
{
"parts": [
{
"text": "这是一张有人的图片"
},
{
"inline_data": {
"mime_type": "image/jpeg",
"data": image_to_base64(human_filepath, False)
}
},
{
"text": "这是另外一张有衣服,裤子或者裙子,鞋子,手表,耳环和其他各种可以穿戴在身上物品的图片"
},
{
"inline_data": {
"mime_type": "image/jpeg",
"data": image_to_base64(suit_filepath, False)
}
},
{
"text": "给第一张图片的人物,穿戴上第二张图片的衣服和配饰"
}
]
}
]
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk-zLFhpbBQKWV4qohV4vD0AFR6Gaa7JwL0Q8zphh1CYFl2EqDM'
}
conn.request("POST", "/v1beta/models/gemini-2.5-flash-image-preview:generateContent", payload, headers)
res = conn.getresponse()
data = res.read()
decode_str = data.decode("utf-8")
img_data = get_image_from_json(decode_str)
image_stream = BytesIO(img_data)
image = Image.open(image_stream)
jpg_name = f"{uuid.uuid4()}.png"
jpg_path_name = f'{APP_ROOT}/static/imgs/{jpg_name}'
image.save(jpg_path_name, quality=90)
upload_to_oss(jpg_path_name, jpg_name)
https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/{jpg_name}'
if img_data:
if 'base64' in output_format:
return jsonify({
"ret":0,
"state": 0,
"msg":"success",
"data":image_to_base64(jpg_path_name)
})
else:
return jsonify({
"ret":0,
"state": 0,
"msg":"success",
"url":https_url
})
else:
return jsonify({
"ret":-1,
"state": -1,
"msg":"failure"
})
def process_change_cloth(human_filename, cloth_filename, output_format, img_url, human_url, no2, tuodi, kuzi_url, cloth_len, kuzi_img=None):
w,h = get_image_dimensions(f'{APP_ROOT}/../input/{human_filename}')
if kuzi_url:
print(f'换裤子 kuzi_url:{kuzi_url}')
human_json_str = GetHumanDesDesc(human_url)
print(f"human_json_str {human_json_str}")
human_json_data = json.loads(human_json_str)
sex_type = human_json_data['性别']
sex_girl = True
if '' in sex_type:
sex_girl = False
new_data = {
"model_image": image_to_base64(f'{APP_ROOT}/../input/{human_filename}', False),
"shirt_image": image_to_base64(f'{APP_ROOT}/../input/{cloth_filename}', False),
"pants_image": kuzi_img if kuzi_img else image_to_base64(save_image_from_url(kuzi_url), False),
}
response = requests.post(f'http://117.50.44.174:47698/try-on', json=new_data)
result_image_data = response.json().get("result_image", "")
if result_image_data:
print(f"result_image_data: {result_image_data[:30]}...") # 打印前30个字符以验证数据格式
if 'base64' in output_format:
return jsonify({
"ret":0,
"state": 0,
"msg":"success",
"is_girl":sex_girl,
"second_step_data":new_data["model_image"],
"first_step_data":new_data["model_image"],
"data":result_image_data
})
else:
result_image_bytes = base64.b64decode(result_image_data.split(',')[1])
result_image_stream = BytesIO(result_image_bytes)
image = Image.open(result_image_stream)
jpg_name = f"{uuid.uuid4()}.png"
jpg_path_name = f'{APP_ROOT}/static/imgs/{jpg_name}'
image.save(jpg_path_name, quality=90)
upload_to_oss(jpg_path_name, jpg_name)
https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/{jpg_name}'
return jsonify({
"ret":0,
"state": 0,
"msg":"success",
"second_url":https_url,
"first_url":https_url,
"is_girl":sex_girl,
"url":https_url
})
out_put_name, out_human_name, is_girl, msg = change(human_filename, cloth_filename, w, h, img_url, human_url, no2, tuodi, cloth_len)
if out_put_name == None: if out_put_name == None:
print(f'Failed to change cloth {msg}') print(f'Failed to change cloth {msg}')
return jsonify({"ret":-1, 'msg': f'Failed to change cloth {msg}'}), 200 return jsonify({"ret":-1, 'msg': f'Failed to change cloth {msg}'}), 200
@@ -449,30 +716,53 @@ def process_change_cloth(human_filename, cloth_filename, output_format, img_url,
if no2: if no2:
out_human_https_url = human_url out_human_https_url = human_url
else: else:
out_human_image = Image.open(f'/home/szlc/code/ComfyUI/output/{out_human_name}') if os.path.exists(f'{APP_ROOT}/../output/{out_human_name}'):
out_human_image = Image.open(f'{APP_ROOT}/../output/{out_human_name}')
else:
out_human_image = Image.open(f'{APP_ROOT}/../input/{out_human_name}')
out_human_jpg_name = out_human_name.replace(".png", ".jpg") out_human_jpg_name = out_human_name.replace(".png", ".jpg")
out_human_jpg_path_name = f'/home/szlc/code/ComfyUI/change_cloth/static/imgs/{out_human_jpg_name}' out_human_jpg_path_name = f'{APP_ROOT}/static/imgs/{out_human_jpg_name}'
out_human_image.save(out_human_jpg_path_name, quality=95) out_human_image.save(out_human_jpg_path_name, quality=90)
upload_to_oss(out_human_jpg_path_name, out_human_jpg_name) # 第二个参数可选,指定OSS上的路径 upload_to_oss(out_human_jpg_path_name, out_human_jpg_name) # 第二个参数可选,指定OSS上的路径
out_human_https_url = f'https://llyz.oss-cn-beijing.aliyuncs.com/{out_human_jpg_name}' out_human_https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/{out_human_jpg_name}'
print(f"生成的第一步图片 HTTPS URL: {out_human_https_url}") print(f"生成的第一步图片 HTTPS URL: {out_human_https_url}")
image = Image.open(f'{APP_ROOT}/../output/{out_put_name}')
image = Image.open(f'/home/szlc/code/ComfyUI/output/{out_put_name}')
jpg_name = out_put_name.replace(".png", ".jpg") jpg_name = out_put_name.replace(".png", ".jpg")
jpg_path_name = f'/home/szlc/code/ComfyUI/change_cloth/static/imgs/{jpg_name}' jpg_path_name = f'{APP_ROOT}/static/imgs/{jpg_name}'
image.save(jpg_path_name, quality=95) image.save(jpg_path_name, quality=90)
upload_to_oss(jpg_path_name, jpg_name) # 第二个参数可选,指定OSS上的路径 upload_to_oss(jpg_path_name, jpg_name) # 第二个参数可选,指定OSS上的路径
https_url = f'https://llyz.oss-cn-beijing.aliyuncs.com/{jpg_name}' https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/{jpg_name}'
print(f"生成的HTTPS URL: {https_url}") print(f"生成的HTTPS URL: {https_url}")
out_befor_kuzi_url = https_url
if kuzi_url:
output_path_name = os.path.join(f'{APP_ROOT}/../output', out_put_name)
output_path_name_input = os.path.join(f'{APP_ROOT}/../input', out_put_name)
shutil.copy(output_path_name, output_path_name_input)
kuzi_filename = save_image_from_url(kuzi_url)
kuzi_out_put_name, msg = change_kuzi(out_put_name, kuzi_filename)
image = Image.open(f'{APP_ROOT}/../output/{kuzi_out_put_name}')
jpg_name = kuzi_out_put_name.replace(".png", ".jpg")
jpg_path_name = f'{APP_ROOT}/static/imgs/{jpg_name}'
image.save(jpg_path_name, quality=90)
upload_to_oss(jpg_path_name, jpg_name) # 第二个参数可选,指定OSS上的路径
https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/{jpg_name}'
print(f"生成的加上换裤子的 HTTPS URL: {https_url}")
if 'base64' in output_format: if 'base64' in output_format:
return jsonify({ return jsonify({
"ret":0, "ret":0,
"state": 0, "state": 0,
"msg":"success", "msg":"success",
"second_step_data":image_to_base64(out_befor_kuzi_url),
"first_step_data":image_to_base64(out_human_jpg_path_name), "first_step_data":image_to_base64(out_human_jpg_path_name),
"is_girl":is_girl, "is_girl":is_girl,
"data":image_to_base64(jpg_path_name) "data":image_to_base64(jpg_path_name)
@@ -482,6 +772,7 @@ def process_change_cloth(human_filename, cloth_filename, output_format, img_url,
"ret":0, "ret":0,
"state": 0, "state": 0,
"msg":"success", "msg":"success",
"second_url":out_befor_kuzi_url,
"first_url":out_human_https_url, "first_url":out_human_https_url,
"is_girl":is_girl, "is_girl":is_girl,
"url":https_url "url":https_url
@@ -510,13 +801,13 @@ def save_image_from_url(image_url):
# 获取原始图片格式 # 获取原始图片格式
ext = get_file_extension(image_url) ext = get_file_extension(image_url)
filename = f"{uuid.uuid4()}{ext}" filename = f"{uuid.uuid4()}{ext}"
filepath = os.path.join('/home/szlc/code/ComfyUI/change_cloth/static/imgs', filename) filepath = os.path.join(f'{APP_ROOT}/static/imgs', filename)
with open(filepath, "wb") as f: with open(filepath, "wb") as f:
for chunk in response.iter_content(1024): for chunk in response.iter_content(1024):
f.write(chunk) f.write(chunk)
input_filepath = os.path.join('/home/szlc/code/ComfyUI/input', filename) input_filepath = os.path.join(f'{APP_ROOT}/../input', filename)
shutil.copy(filepath, input_filepath) shutil.copy(filepath, input_filepath)
return filename return filename
@@ -525,11 +816,20 @@ def save_image_from_url(image_url):
return None return None
@app.route('/')
def index():
"""返回主页"""
from flask import send_from_directory
return send_from_directory('static', 'index.html')
@app.route('/do_change_cloth', methods=['POST']) @app.route('/do_change_cloth', methods=['POST'])
def do_change_cloth(): def do_change_cloth():
log_message("do_change_cloth called")
"""从 URL 下载图片""" """从 URL 下载图片"""
data = request.json data = request.json
print(f"do_change_cloth input data:{data}")
human_url = data.get("human_url") human_url = data.get("human_url")
human_filename = save_image_from_url(human_url) human_filename = save_image_from_url(human_url)
@@ -543,6 +843,10 @@ def do_change_cloth():
output_format = data.get('output_format') output_format = data.get('output_format')
if 'suit' in data:
if data['suit']:
return process_change_banana(human_filename, cloth_filename, output_format)
def check_type(var): def check_type(var):
if isinstance(var, bool): if isinstance(var, bool):
print(f"{var} 是布尔值no2") print(f"{var} 是布尔值no2")
@@ -551,12 +855,29 @@ def do_change_cloth():
else: else:
print(f"既不是字符串也不是布尔值no2,实际类型: {type(var)}") print(f"既不是字符串也不是布尔值no2,实际类型: {type(var)}")
no2 = data['no2'] no2 = False
check_type(no2) if 'no2' in data:
no2 = data['no2']
check_type(no2)
tuodi = False
if 'tuodi' in data:
tuodi = data['tuodi']
print(f"tuodi:{tuodi}")
kuzi_url = None
if 'kuzi_url' in data:
kuzi_url = data.get("kuzi_url")
print(f"要弄裤子 kuzi:{kuzi_url}")
cloth_len = None
if 'cloth_len' in data:
cloth_len = data['cloth_len']
try: try:
return process_change_cloth(human_filename, cloth_filename, output_format, cloth_url, human_url, no2) return process_change_cloth(human_filename, cloth_filename, output_format, cloth_url, human_url, no2, tuodi, kuzi_url, cloth_len, data.get("kuzi_img") )
except: except Exception as e:
traceback.print_exc()
print(f"错误详情:{e}")
return jsonify({ return jsonify({
"ret":-1, "ret":-1,
"state": -1, "state": -1,
@@ -611,6 +932,7 @@ def queueCall(data):
@app.route('/change_cloth', methods=['POST']) @app.route('/change_cloth', methods=['POST'])
def change_cloth(): def change_cloth():
log_message("change_cloth_base64 called")
"""从 URL 下载图片""" """从 URL 下载图片"""
data = request.json data = request.json
@@ -630,14 +952,25 @@ def change_cloth():
if not no2: if not no2:
data['no2'] = False data['no2'] = False
tuodi = data.get('tuodi')
if not tuodi:
data['tuodi'] = False
kuzi = data.get('kuzi')
if not kuzi:
data['kuzi'] = False
print(f"change_cloth input data:{data}") print(f"change_cloth input data:{data}")
return queueCall(data) return queueCall(data)
@app.route('/change_cloth_base64', methods=['POST']) @app.route('/change_cloth_base64', methods=['POST'])
def change_cloth_base64(): def change_cloth_base64():
log_message("change_cloth_base64 called")
# 获取参数 # 获取参数
data = request.get_json() data = request.get_json()
print(f"change_cloth_base64 input data:{data}")
if not data: if not data:
return jsonify({"ret":-1, "state":-1, 'msg': 'No JSON data provided'}), 400 return jsonify({"ret":-1, "state":-1, 'msg': 'No JSON data provided'}), 400
@@ -655,7 +988,7 @@ def change_cloth_base64():
return jsonify({"ret":-1, 'msg': 'Failed to save human image'}), 500 return jsonify({"ret":-1, 'msg': 'Failed to save human image'}), 500
data['human_img'] = None data['human_img'] = None
human_url = f"http://112.126.94.241:18888/static/imgs/{human_filename}" human_url = f"http://117.50.44.174:{base64_test_port}/static/imgs/{human_filename}"
# 保存服装图片 # 保存服装图片
cloth_filename = save_base64_image(cloth_img, 'cloth') cloth_filename = save_base64_image(cloth_img, 'cloth')
@@ -663,17 +996,51 @@ def change_cloth_base64():
return jsonify({"ret":-1, 'msg': 'Failed to save cloth image'}), 500 return jsonify({"ret":-1, 'msg': 'Failed to save cloth image'}), 500
data['cloth_img'] = None data['cloth_img'] = None
cloth_url = f"http://112.126.94.241:18888/static/imgs/{cloth_filename}" cloth_url = f"http://117.50.44.174:{base64_test_port}/static/imgs/{cloth_filename}"
data["human_url"] = human_url data["human_url"] = human_url
data["cloth_url"] = cloth_url data["cloth_url"] = cloth_url
kuzi_img = data.get('kuzi_img')
if kuzi_img:
kuzi_filename = save_base64_image(kuzi_img, 'kuzi')
# data['kuzi_img'] = None
kuzi_url = f"http://117.50.44.174:{base64_test_port}/static/imgs/{kuzi_filename}"
data['kuzi_url'] = kuzi_url
no2 = data.get('no2') no2 = data.get('no2')
if not no2: if not no2:
data['no2'] = False data['no2'] = False
return queueCall(data) tuodi = data.get('tuodi')
if not tuodi:
data['tuodi'] = False
if not data.get('suit'):
data['suit'] = False
if data.get('cloth_len'):
print(f'客户端传入了衣服长度: {data['cloth_len']}')
else:
print('客户端传入了衣服长度,需要ai 判断')
# 在内部调用第二个HTTP请求
try:
# 调用第二个API(可以是外部服务或自己的另一个端点)
response = requests.post(f'http://117.50.44.174:{base64_test_port}/do_change_cloth', json=data)
return Response(
response=response.content,
status=response.status_code,
headers=dict(response.headers)
)
except requests.exceptions.RequestException as e:
data['second_api_error'] = str(e)
return jsonify("error"), 500
if __name__ == '__main__': if __name__ == '__main__':
app.run(host="0.0.0.0", port=8888, debug=True) app.run(host="0.0.0.0", port=base64_test_port, debug=False)
+16 -16
View File
@@ -1,7 +1,7 @@
{ {
"3": { "3": {
"inputs": { "inputs": {
"seed": 154943414582783, "seed": 940724765309123,
"steps": 20, "steps": 20,
"cfg": 1, "cfg": 1,
"sampler_name": "euler", "sampler_name": "euler",
@@ -73,7 +73,7 @@
}, },
"10": { "10": {
"inputs": { "inputs": {
"strength": 1, "strength": 1.0000000000000002,
"strength_type": "multiply", "strength_type": "multiply",
"conditioning": [ "conditioning": [
"11", "11",
@@ -196,7 +196,7 @@
}, },
"22": { "22": {
"inputs": { "inputs": {
"image": "cloth_20250715_232138_50414b8f.jpg" "image": "0b0a7d75-3241-49b5-be98-5dc87838322c.jpg"
}, },
"class_type": "LoadImage", "class_type": "LoadImage",
"_meta": { "_meta": {
@@ -254,7 +254,7 @@
"27": { "27": {
"inputs": { "inputs": {
"context_expand_pixels": 20, "context_expand_pixels": 20,
"context_expand_factor": 1, "context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true, "fill_mask_holes": true,
"blur_mask_pixels": 10, "blur_mask_pixels": 10,
"invert_mask": false, "invert_mask": false,
@@ -263,7 +263,7 @@
"mode": "ranged size", "mode": "ranged size",
"force_width": 1024, "force_width": 1024,
"force_height": 1024, "force_height": 1024,
"rescale_factor": 1, "rescale_factor": 1.0000000000000002,
"min_width": 512, "min_width": 512,
"min_height": 512, "min_height": 512,
"max_width": 1800, "max_width": 1800,
@@ -467,9 +467,9 @@
"59": { "59": {
"inputs": { "inputs": {
"brightness": -1, "brightness": -1,
"contrast": 1, "contrast": 1.0000000000000002,
"saturation": 1, "saturation": 1.0000000000000002,
"sharpness": 1, "sharpness": 1.0000000000000002,
"blur": 0, "blur": 0,
"gaussian_blur": 48.1, "gaussian_blur": 48.1,
"edge_enhance": 0, "edge_enhance": 0,
@@ -486,7 +486,7 @@
}, },
"61": { "61": {
"inputs": { "inputs": {
"image": "75857233_00001_.png" "image": "c599a298-2992-487d-95f0-be5e6c08e8c8.png"
}, },
"class_type": "LoadImage", "class_type": "LoadImage",
"_meta": { "_meta": {
@@ -495,7 +495,7 @@
}, },
"75": { "75": {
"inputs": { "inputs": {
"model_path": "svdq-int4-flux.1-fill-dev", "model_path": "svdq-fp4_r32-flux.1-fill-dev.safetensors",
"cache_threshold": 0, "cache_threshold": 0,
"attention": "nunchaku-fp16", "attention": "nunchaku-fp16",
"cpu_offload": "auto", "cpu_offload": "auto",
@@ -639,7 +639,7 @@
}, },
"94": { "94": {
"inputs": { "inputs": {
"value": 1024 "value": 2048
}, },
"class_type": "PrimitiveInt", "class_type": "PrimitiveInt",
"_meta": { "_meta": {
@@ -668,7 +668,7 @@
"96": { "96": {
"inputs": { "inputs": {
"cloth_len": "小腿", "cloth_len": "小腿",
"line_len": 0.6000000000000001, "line_len": 0.4,
"cloth_short": true, "cloth_short": true,
"kps": [ "kps": [
"95", "95",
@@ -819,7 +819,7 @@
}, },
"110": { "110": {
"inputs": { "inputs": {
"preview": "1180672", "preview": "855040",
"source": [ "source": [
"106", "106",
0 0
@@ -832,7 +832,7 @@
}, },
"111": { "111": {
"inputs": { "inputs": {
"preview": "768", "preview": "522",
"source": [ "source": [
"108", "108",
0 0
@@ -858,7 +858,7 @@
}, },
"113": { "113": {
"inputs": { "inputs": {
"preview": "1793", "preview": "1547",
"source": [ "source": [
"107", "107",
0 0
@@ -975,7 +975,7 @@
"71:2": { "71:2": {
"inputs": { "inputs": {
"prompt": "cloth", "prompt": "cloth",
"threshold": 0.3, "threshold": 0.30000000000000004,
"sam_model": [ "sam_model": [
"71:0", "71:0",
0 0
+961
View File
@@ -0,0 +1,961 @@
{
"3": {
"inputs": {
"seed": 133974548609577,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"17",
0
],
"negative": [
"17",
1
],
"latent_image": [
"17",
2
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"16",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"strength": 1.0000000000000002,
"strength_type": "multiply",
"conditioning": [
"11",
0
],
"style_model": [
"79",
0
],
"clip_vision_output": [
"20",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "Apply Style Model"
}
},
"11": {
"inputs": {
"guidance": 30,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"12": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"13": {
"inputs": {
"model": [
"75",
0
]
},
"class_type": "DifferentialDiffusion",
"_meta": {
"title": "Differential Diffusion"
}
},
"16": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"17": {
"inputs": {
"noise_mask": false,
"positive": [
"10",
0
],
"negative": [
"7",
0
],
"vae": [
"16",
0
],
"pixels": [
"27",
1
],
"mask": [
"27",
2
]
},
"class_type": "InpaintModelConditioning",
"_meta": {
"title": "InpaintModelConditioning"
}
},
"20": {
"inputs": {
"crop": "center",
"clip_vision": [
"21",
0
],
"image": [
"25",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP Vision Encode"
}
},
"21": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "Load CLIP Vision"
}
},
"22": {
"inputs": {
"image": "man_cloth.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"25": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"22",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"26": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"61",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"27": {
"inputs": {
"context_expand_pixels": 20,
"context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true,
"blur_mask_pixels": 10,
"invert_mask": false,
"blend_pixels": 16,
"rescale_algorithm": "bicubic",
"mode": "ranged size",
"force_width": 1024,
"force_height": 1024,
"rescale_factor": 1.0000000000000002,
"min_width": 512,
"min_height": 512,
"max_width": 1800,
"max_height": 1800,
"padding": 32,
"image": [
"42",
0
],
"mask": [
"30",
0
],
"optional_context_mask": [
"40",
0
]
},
"class_type": "InpaintCrop",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Crop node)"
}
},
"28": {
"inputs": {
"mask": [
"127",
0
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"29": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"28",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"30": {
"inputs": {
"channel": "red",
"image": [
"43",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"34": {
"inputs": {
"rescale_algorithm": "bislerp",
"stitch": [
"27",
0
],
"inpainted_image": [
"8",
0
]
},
"class_type": "InpaintStitch",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Stitch node)"
}
},
"37": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"38",
0
],
"image2": [
"57",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"38": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"40": {
"inputs": {
"channel": "red",
"image": [
"37",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"42": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"25",
0
],
"image2": [
"26",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"43": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"59",
0
],
"image2": [
"29",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"45": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"57": {
"inputs": {
"brightness": -1,
"contrast": 0,
"saturation": 0,
"sharpness": 0,
"blur": 0,
"gaussian_blur": 0,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"26",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"59": {
"inputs": {
"brightness": -1,
"contrast": 1.0000000000000002,
"saturation": 1.0000000000000002,
"sharpness": 1.0000000000000002,
"blur": 0,
"gaussian_blur": 48.1,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"25",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"61": {
"inputs": {
"image": "微信图片_20250808213937_73.png"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"75": {
"inputs": {
"model_path": "svdq-int4-flux.1-fill-dev",
"cache_threshold": 0,
"attention": "nunchaku-fp16",
"cpu_offload": "auto",
"device_id": 0,
"data_type": "bfloat16",
"i2f_mode": "enabled"
},
"class_type": "NunchakuFluxDiTLoader",
"_meta": {
"title": "Nunchaku FLUX DiT Loader"
}
},
"79": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "Load Style Model"
}
},
"83": {
"inputs": {
"images": [
"29",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"84": {
"inputs": {
"images": [
"43",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"85": {
"inputs": {
"mask": [
"30",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"86": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskPreview+",
"_meta": {
"title": "🔧 Mask Preview"
}
},
"87": {
"inputs": {
"images": [
"38",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"88": {
"inputs": {
"images": [
"37",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"89": {
"inputs": {
"images": [
"57",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"90": {
"inputs": {
"images": [
"59",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"91": {
"inputs": {
"images": [
"27",
1
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"93": {
"inputs": {
"mask": [
"27",
2
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"94": {
"inputs": {
"value": 1536
},
"class_type": "PrimitiveInt",
"_meta": {
"title": "Int"
}
},
"95": {
"inputs": {
"detect_hand": "disable",
"detect_body": "enable",
"detect_face": "disable",
"resolution": 512,
"bbox_detector": "yolo_nas_m_fp16.onnx",
"pose_estimator": "dw-ll_ucoco_384.onnx",
"scale_stick_for_xinsr_cn": "disable",
"image": [
"61",
0
]
},
"class_type": "DWPreprocessor",
"_meta": {
"title": "DWPose Estimator"
}
},
"96": {
"inputs": {
"cloth_len": "拖地",
"line_len": 0.4000000000000001,
"cloth_short": true,
"kps": [
"95",
1
]
},
"class_type": "RenderPeopleKpsMask",
"_meta": {
"title": "My RenderPeopleKps Mask"
}
},
"98": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"99": {
"inputs": {
"width": [
"108",
0
],
"height": [
"107",
1
],
"x": [
"109",
0
],
"y": 0,
"image": [
"34",
0
]
},
"class_type": "ImageCrop",
"_meta": {
"title": "Image Crop"
}
},
"102": {
"inputs": {
"filename_prefix": "my_test_out",
"images": [
"99",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"104": {
"inputs": {
"image": [
"61",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"106": {
"inputs": {
"op": "Mul",
"a": [
"107",
1
],
"b": [
"104",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"107": {
"inputs": {
"image": [
"34",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"108": {
"inputs": {
"op": "Div",
"a": [
"106",
0
],
"b": [
"104",
1
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"109": {
"inputs": {
"op": "Sub",
"a": [
"107",
0
],
"b": [
"108",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"119": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"120": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"124": {
"inputs": {
"images": [
"95",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"125": {
"inputs": {
"prompt": "people",
"threshold": 0.9,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"61",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"126": {
"inputs": {
"mask": [
"125",
1
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"127": {
"inputs": {
"x": 0,
"y": 0,
"operation": "add",
"destination": [
"96",
0
],
"source": [
"125",
1
]
},
"class_type": "MaskComposite",
"_meta": {
"title": "MaskComposite"
}
},
"128": {
"inputs": {
"mask": [
"127",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"71:1": {
"inputs": {
"model_name": "GroundingDINO_SwinT_OGC (694MB)"
},
"class_type": "GroundingDinoModelLoader (segment anything)",
"_meta": {
"title": "GroundingDinoModelLoader (segment anything)"
}
},
"71:0": {
"inputs": {
"model_name": "sam_vit_h (2.56GB)"
},
"class_type": "SAMModelLoader (segment anything)",
"_meta": {
"title": "SAMModelLoader (segment anything)"
}
},
"71:2": {
"inputs": {
"prompt": "cloth",
"threshold": 0.30000000000000004,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"25",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"71:3": {
"inputs": {
"images": [
"71:2",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
}
}
+970
View File
@@ -0,0 +1,970 @@
{
"3": {
"inputs": {
"seed": 195628935144004,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"17",
0
],
"negative": [
"17",
1
],
"latent_image": [
"17",
2
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"16",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"strength": 1.0000000000000002,
"strength_type": "multiply",
"conditioning": [
"11",
0
],
"style_model": [
"79",
0
],
"clip_vision_output": [
"20",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "Apply Style Model"
}
},
"11": {
"inputs": {
"guidance": 30,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"12": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"13": {
"inputs": {
"model": [
"75",
0
]
},
"class_type": "DifferentialDiffusion",
"_meta": {
"title": "Differential Diffusion"
}
},
"16": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"17": {
"inputs": {
"noise_mask": false,
"positive": [
"10",
0
],
"negative": [
"7",
0
],
"vae": [
"16",
0
],
"pixels": [
"27",
1
],
"mask": [
"27",
2
]
},
"class_type": "InpaintModelConditioning",
"_meta": {
"title": "InpaintModelConditioning"
}
},
"20": {
"inputs": {
"crop": "center",
"clip_vision": [
"21",
0
],
"image": [
"25",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP Vision Encode"
}
},
"21": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "Load CLIP Vision"
}
},
"22": {
"inputs": {
"image": "微信图片_20250810123345_95.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"25": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"22",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"26": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"61",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"27": {
"inputs": {
"context_expand_pixels": 20,
"context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true,
"blur_mask_pixels": 10,
"invert_mask": false,
"blend_pixels": 16,
"rescale_algorithm": "bicubic",
"mode": "ranged size",
"force_width": 1024,
"force_height": 1024,
"rescale_factor": 1.0000000000000002,
"min_width": 512,
"min_height": 512,
"max_width": 1800,
"max_height": 1800,
"padding": 32,
"image": [
"42",
0
],
"mask": [
"30",
0
],
"optional_context_mask": [
"40",
0
]
},
"class_type": "InpaintCrop",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Crop node)"
}
},
"28": {
"inputs": {
"mask": [
"129",
0
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"29": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"28",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"30": {
"inputs": {
"channel": "red",
"image": [
"43",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"34": {
"inputs": {
"rescale_algorithm": "bislerp",
"stitch": [
"27",
0
],
"inpainted_image": [
"8",
0
]
},
"class_type": "InpaintStitch",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Stitch node)"
}
},
"37": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"38",
0
],
"image2": [
"57",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"38": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"40": {
"inputs": {
"channel": "red",
"image": [
"37",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"42": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"25",
0
],
"image2": [
"26",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"43": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"59",
0
],
"image2": [
"29",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"45": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"57": {
"inputs": {
"brightness": -1,
"contrast": 0,
"saturation": 0,
"sharpness": 0,
"blur": 0,
"gaussian_blur": 0,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"26",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"59": {
"inputs": {
"brightness": -1,
"contrast": 1.0000000000000002,
"saturation": 1.0000000000000002,
"sharpness": 1.0000000000000002,
"blur": 0,
"gaussian_blur": 48.1,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"25",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"61": {
"inputs": {
"image": "微信图片_20250810122705_94.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"75": {
"inputs": {
"model_path": "svdq-int4-flux.1-fill-dev",
"cache_threshold": 0,
"attention": "nunchaku-fp16",
"cpu_offload": "auto",
"device_id": 0,
"data_type": "bfloat16",
"i2f_mode": "enabled"
},
"class_type": "NunchakuFluxDiTLoader",
"_meta": {
"title": "Nunchaku FLUX DiT Loader"
}
},
"79": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "Load Style Model"
}
},
"83": {
"inputs": {
"images": [
"29",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"84": {
"inputs": {
"images": [
"43",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"85": {
"inputs": {
"mask": [
"30",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"86": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskPreview+",
"_meta": {
"title": "🔧 Mask Preview"
}
},
"87": {
"inputs": {
"images": [
"38",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"88": {
"inputs": {
"images": [
"37",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"89": {
"inputs": {
"images": [
"57",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"90": {
"inputs": {
"images": [
"59",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"91": {
"inputs": {
"images": [
"27",
1
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"93": {
"inputs": {
"mask": [
"27",
2
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"94": {
"inputs": {
"value": 1536
},
"class_type": "PrimitiveInt",
"_meta": {
"title": "Int"
}
},
"95": {
"inputs": {
"detect_hand": "disable",
"detect_body": "enable",
"detect_face": "disable",
"resolution": 512,
"bbox_detector": "yolo_nas_m_fp16.onnx",
"pose_estimator": "dw-ll_ucoco_384.onnx",
"scale_stick_for_xinsr_cn": "disable",
"image": [
"61",
0
]
},
"class_type": "DWPreprocessor",
"_meta": {
"title": "DWPose Estimator"
}
},
"96": {
"inputs": {
"cloth_len": "腰",
"line_len": 0.4000000000000001,
"cloth_short": true,
"width": 0,
"height": 0,
"left_right_line_width": 1,
"human_head2_yao_times": 2.5,
"more_clip": 0.1,
"kps": [
"95",
1
]
},
"class_type": "RenderPeopleKpsMask",
"_meta": {
"title": "My RenderPeopleKps Mask"
}
},
"98": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"99": {
"inputs": {
"width": [
"108",
0
],
"height": [
"107",
1
],
"x": [
"109",
0
],
"y": 0,
"image": [
"34",
0
]
},
"class_type": "ImageCrop",
"_meta": {
"title": "Image Crop"
}
},
"102": {
"inputs": {
"filename_prefix": "my_test_out",
"images": [
"99",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"104": {
"inputs": {
"image": [
"61",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"106": {
"inputs": {
"op": "Mul",
"a": [
"107",
1
],
"b": [
"104",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"107": {
"inputs": {
"image": [
"34",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"108": {
"inputs": {
"op": "Div",
"a": [
"106",
0
],
"b": [
"104",
1
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"109": {
"inputs": {
"op": "Sub",
"a": [
"107",
0
],
"b": [
"108",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"119": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"120": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"124": {
"inputs": {
"images": [
"95",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"125": {
"inputs": {
"prompt": "people",
"threshold": 0.9,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"61",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"126": {
"inputs": {
"mask": [
"125",
1
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"129": {
"inputs": {
"x": 0,
"y": 0,
"offset": [
"96",
1
],
"operation": "add",
"destination": [
"96",
0
],
"source": [
"125",
1
]
},
"class_type": "MyMaskComposite",
"_meta": {
"title": "MyMaskComposite"
}
},
"130": {
"inputs": {
"mask": [
"129",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"71:1": {
"inputs": {
"model_name": "GroundingDINO_SwinT_OGC (694MB)"
},
"class_type": "GroundingDinoModelLoader (segment anything)",
"_meta": {
"title": "GroundingDinoModelLoader (segment anything)"
}
},
"71:0": {
"inputs": {
"model_name": "sam_vit_h (2.56GB)"
},
"class_type": "SAMModelLoader (segment anything)",
"_meta": {
"title": "SAMModelLoader (segment anything)"
}
},
"71:2": {
"inputs": {
"prompt": "cloth",
"threshold": 0.30000000000000004,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"25",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"71:3": {
"inputs": {
"images": [
"71:2",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
}
}
+961
View File
@@ -0,0 +1,961 @@
{
"3": {
"inputs": {
"seed": 627869097640777,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"17",
0
],
"negative": [
"17",
1
],
"latent_image": [
"17",
2
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"16",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"strength": 1.0000000000000002,
"strength_type": "multiply",
"conditioning": [
"11",
0
],
"style_model": [
"79",
0
],
"clip_vision_output": [
"20",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "Apply Style Model"
}
},
"11": {
"inputs": {
"guidance": 30,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"12": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"13": {
"inputs": {
"model": [
"75",
0
]
},
"class_type": "DifferentialDiffusion",
"_meta": {
"title": "Differential Diffusion"
}
},
"16": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"17": {
"inputs": {
"noise_mask": false,
"positive": [
"10",
0
],
"negative": [
"7",
0
],
"vae": [
"16",
0
],
"pixels": [
"27",
1
],
"mask": [
"27",
2
]
},
"class_type": "InpaintModelConditioning",
"_meta": {
"title": "InpaintModelConditioning"
}
},
"20": {
"inputs": {
"crop": "center",
"clip_vision": [
"21",
0
],
"image": [
"25",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP Vision Encode"
}
},
"21": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "Load CLIP Vision"
}
},
"22": {
"inputs": {
"image": "man_cloth.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"25": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"22",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"26": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"61",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"27": {
"inputs": {
"context_expand_pixels": 20,
"context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true,
"blur_mask_pixels": 10,
"invert_mask": false,
"blend_pixels": 16,
"rescale_algorithm": "bicubic",
"mode": "ranged size",
"force_width": 1024,
"force_height": 1024,
"rescale_factor": 1.0000000000000002,
"min_width": 512,
"min_height": 512,
"max_width": 1800,
"max_height": 1800,
"padding": 32,
"image": [
"42",
0
],
"mask": [
"30",
0
],
"optional_context_mask": [
"40",
0
]
},
"class_type": "InpaintCrop",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Crop node)"
}
},
"28": {
"inputs": {
"mask": [
"127",
0
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"29": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"28",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"30": {
"inputs": {
"channel": "red",
"image": [
"43",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"34": {
"inputs": {
"rescale_algorithm": "bislerp",
"stitch": [
"27",
0
],
"inpainted_image": [
"8",
0
]
},
"class_type": "InpaintStitch",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Stitch node)"
}
},
"37": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"38",
0
],
"image2": [
"57",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"38": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"40": {
"inputs": {
"channel": "red",
"image": [
"37",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"42": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"25",
0
],
"image2": [
"26",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"43": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"59",
0
],
"image2": [
"29",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"45": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"57": {
"inputs": {
"brightness": -1,
"contrast": 0,
"saturation": 0,
"sharpness": 0,
"blur": 0,
"gaussian_blur": 0,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"26",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"59": {
"inputs": {
"brightness": -1,
"contrast": 1.0000000000000002,
"saturation": 1.0000000000000002,
"sharpness": 1.0000000000000002,
"blur": 0,
"gaussian_blur": 48.1,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"25",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"61": {
"inputs": {
"image": "微信图片_20250808213937_73.png"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"75": {
"inputs": {
"model_path": "svdq-fp4_r32-flux.1-fill-dev.safetensors",
"cache_threshold": 0,
"attention": "nunchaku-fp16",
"cpu_offload": "auto",
"device_id": 0,
"data_type": "bfloat16",
"i2f_mode": "enabled"
},
"class_type": "NunchakuFluxDiTLoader",
"_meta": {
"title": "Nunchaku FLUX DiT Loader"
}
},
"79": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "Load Style Model"
}
},
"83": {
"inputs": {
"images": [
"29",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"84": {
"inputs": {
"images": [
"43",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"85": {
"inputs": {
"mask": [
"30",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"86": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskPreview+",
"_meta": {
"title": "🔧 Mask Preview"
}
},
"87": {
"inputs": {
"images": [
"38",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"88": {
"inputs": {
"images": [
"37",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"89": {
"inputs": {
"images": [
"57",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"90": {
"inputs": {
"images": [
"59",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"91": {
"inputs": {
"images": [
"27",
1
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"93": {
"inputs": {
"mask": [
"27",
2
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"94": {
"inputs": {
"value": 2048
},
"class_type": "PrimitiveInt",
"_meta": {
"title": "Int"
}
},
"95": {
"inputs": {
"detect_hand": "disable",
"detect_body": "enable",
"detect_face": "disable",
"resolution": 512,
"bbox_detector": "yolo_nas_m_fp16.onnx",
"pose_estimator": "dw-ll_ucoco_384.onnx",
"scale_stick_for_xinsr_cn": "disable",
"image": [
"61",
0
]
},
"class_type": "DWPreprocessor",
"_meta": {
"title": "DWPose Estimator"
}
},
"96": {
"inputs": {
"cloth_len": "拖地",
"line_len": 0.4000000000000001,
"cloth_short": true,
"kps": [
"95",
1
]
},
"class_type": "RenderPeopleKpsMask",
"_meta": {
"title": "My RenderPeopleKps Mask"
}
},
"98": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"99": {
"inputs": {
"width": [
"108",
0
],
"height": [
"107",
1
],
"x": [
"109",
0
],
"y": 0,
"image": [
"34",
0
]
},
"class_type": "ImageCrop",
"_meta": {
"title": "Image Crop"
}
},
"102": {
"inputs": {
"filename_prefix": "my_test_out",
"images": [
"99",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"104": {
"inputs": {
"image": [
"61",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"106": {
"inputs": {
"op": "Mul",
"a": [
"107",
1
],
"b": [
"104",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"107": {
"inputs": {
"image": [
"34",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"108": {
"inputs": {
"op": "Div",
"a": [
"106",
0
],
"b": [
"104",
1
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"109": {
"inputs": {
"op": "Sub",
"a": [
"107",
0
],
"b": [
"108",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"119": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"120": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"124": {
"inputs": {
"images": [
"95",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"125": {
"inputs": {
"prompt": "people",
"threshold": 0.9,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"61",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"126": {
"inputs": {
"mask": [
"125",
1
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"127": {
"inputs": {
"x": 0,
"y": 0,
"operation": "add",
"destination": [
"96",
0
],
"source": [
"125",
1
]
},
"class_type": "MaskComposite",
"_meta": {
"title": "MaskComposite"
}
},
"128": {
"inputs": {
"mask": [
"127",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"71:1": {
"inputs": {
"model_name": "GroundingDINO_SwinT_OGC (694MB)"
},
"class_type": "GroundingDinoModelLoader (segment anything)",
"_meta": {
"title": "GroundingDinoModelLoader (segment anything)"
}
},
"71:0": {
"inputs": {
"model_name": "sam_vit_h (2.56GB)"
},
"class_type": "SAMModelLoader (segment anything)",
"_meta": {
"title": "SAMModelLoader (segment anything)"
}
},
"71:2": {
"inputs": {
"prompt": "cloth",
"threshold": 0.30000000000000004,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"25",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"71:3": {
"inputs": {
"images": [
"71:2",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
}
}
+970
View File
@@ -0,0 +1,970 @@
{
"3": {
"inputs": {
"seed": 545969317648118,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"17",
0
],
"negative": [
"17",
1
],
"latent_image": [
"17",
2
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"16",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"strength": 1.0000000000000002,
"strength_type": "multiply",
"conditioning": [
"11",
0
],
"style_model": [
"79",
0
],
"clip_vision_output": [
"20",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "Apply Style Model"
}
},
"11": {
"inputs": {
"guidance": 30,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"12": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"13": {
"inputs": {
"model": [
"75",
0
]
},
"class_type": "DifferentialDiffusion",
"_meta": {
"title": "Differential Diffusion"
}
},
"16": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"17": {
"inputs": {
"noise_mask": false,
"positive": [
"10",
0
],
"negative": [
"7",
0
],
"vae": [
"16",
0
],
"pixels": [
"27",
1
],
"mask": [
"27",
2
]
},
"class_type": "InpaintModelConditioning",
"_meta": {
"title": "InpaintModelConditioning"
}
},
"20": {
"inputs": {
"crop": "center",
"clip_vision": [
"21",
0
],
"image": [
"25",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP Vision Encode"
}
},
"21": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "Load CLIP Vision"
}
},
"22": {
"inputs": {
"image": "man_cloth_grey.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"25": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"22",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"26": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"61",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"27": {
"inputs": {
"context_expand_pixels": 20,
"context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true,
"blur_mask_pixels": 10,
"invert_mask": false,
"blend_pixels": 16,
"rescale_algorithm": "bicubic",
"mode": "ranged size",
"force_width": 1024,
"force_height": 1024,
"rescale_factor": 1.0000000000000002,
"min_width": 512,
"min_height": 512,
"max_width": 1800,
"max_height": 1800,
"padding": 32,
"image": [
"42",
0
],
"mask": [
"30",
0
],
"optional_context_mask": [
"40",
0
]
},
"class_type": "InpaintCrop",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Crop node)"
}
},
"28": {
"inputs": {
"mask": [
"129",
0
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"29": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"28",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"30": {
"inputs": {
"channel": "red",
"image": [
"43",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"34": {
"inputs": {
"rescale_algorithm": "bislerp",
"stitch": [
"27",
0
],
"inpainted_image": [
"8",
0
]
},
"class_type": "InpaintStitch",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Stitch node)"
}
},
"37": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"38",
0
],
"image2": [
"57",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"38": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"40": {
"inputs": {
"channel": "red",
"image": [
"37",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"42": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"25",
0
],
"image2": [
"26",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"43": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"59",
0
],
"image2": [
"29",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"45": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"57": {
"inputs": {
"brightness": -1,
"contrast": 0,
"saturation": 0,
"sharpness": 0,
"blur": 0,
"gaussian_blur": 0,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"26",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"59": {
"inputs": {
"brightness": -1,
"contrast": 1.0000000000000002,
"saturation": 1.0000000000000002,
"sharpness": 1.0000000000000002,
"blur": 0,
"gaussian_blur": 48.1,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"25",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"61": {
"inputs": {
"image": "微信图片_20250808213937_73.png"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"75": {
"inputs": {
"model_path": "svdq-fp4_r32-flux.1-fill-dev.safetensors",
"cache_threshold": 0,
"attention": "nunchaku-fp16",
"cpu_offload": "auto",
"device_id": 0,
"data_type": "bfloat16",
"i2f_mode": "enabled"
},
"class_type": "NunchakuFluxDiTLoader",
"_meta": {
"title": "Nunchaku FLUX DiT Loader"
}
},
"79": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "Load Style Model"
}
},
"83": {
"inputs": {
"images": [
"29",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"84": {
"inputs": {
"images": [
"43",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"85": {
"inputs": {
"mask": [
"30",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"86": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskPreview+",
"_meta": {
"title": "🔧 Mask Preview"
}
},
"87": {
"inputs": {
"images": [
"38",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"88": {
"inputs": {
"images": [
"37",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"89": {
"inputs": {
"images": [
"57",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"90": {
"inputs": {
"images": [
"59",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"91": {
"inputs": {
"images": [
"27",
1
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"93": {
"inputs": {
"mask": [
"27",
2
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"94": {
"inputs": {
"value": 2048
},
"class_type": "PrimitiveInt",
"_meta": {
"title": "Int"
}
},
"95": {
"inputs": {
"detect_hand": "disable",
"detect_body": "enable",
"detect_face": "disable",
"resolution": 512,
"bbox_detector": "yolo_nas_m_fp16.onnx",
"pose_estimator": "dw-ll_ucoco_384.onnx",
"scale_stick_for_xinsr_cn": "disable",
"image": [
"61",
0
]
},
"class_type": "DWPreprocessor",
"_meta": {
"title": "DWPose Estimator"
}
},
"96": {
"inputs": {
"cloth_len": "腰",
"line_len": 0.4000000000000001,
"cloth_short": true,
"width": 0,
"height": 0,
"left_right_line_width": 1,
"human_head2_yao_times": 2.5,
"more_clip": 0.1,
"kps": [
"95",
1
]
},
"class_type": "RenderPeopleKpsMask",
"_meta": {
"title": "My RenderPeopleKps Mask"
}
},
"98": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"99": {
"inputs": {
"width": [
"108",
0
],
"height": [
"107",
1
],
"x": [
"109",
0
],
"y": 0,
"image": [
"34",
0
]
},
"class_type": "ImageCrop",
"_meta": {
"title": "Image Crop"
}
},
"102": {
"inputs": {
"filename_prefix": "my_test_out",
"images": [
"99",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"104": {
"inputs": {
"image": [
"61",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"106": {
"inputs": {
"op": "Mul",
"a": [
"107",
1
],
"b": [
"104",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"107": {
"inputs": {
"image": [
"34",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"108": {
"inputs": {
"op": "Div",
"a": [
"106",
0
],
"b": [
"104",
1
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"109": {
"inputs": {
"op": "Sub",
"a": [
"107",
0
],
"b": [
"108",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"119": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"120": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"124": {
"inputs": {
"images": [
"95",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"125": {
"inputs": {
"prompt": "people",
"threshold": 0.9,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"61",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"126": {
"inputs": {
"mask": [
"125",
1
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"129": {
"inputs": {
"x": 0,
"y": 0,
"offset": [
"96",
1
],
"operation": "add",
"destination": [
"96",
0
],
"source": [
"125",
1
]
},
"class_type": "MyMaskComposite",
"_meta": {
"title": "MyMaskComposite"
}
},
"130": {
"inputs": {
"mask": [
"129",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"71:1": {
"inputs": {
"model_name": "GroundingDINO_SwinT_OGC (694MB)"
},
"class_type": "GroundingDinoModelLoader (segment anything)",
"_meta": {
"title": "GroundingDinoModelLoader (segment anything)"
}
},
"71:0": {
"inputs": {
"model_name": "sam_vit_h (2.56GB)"
},
"class_type": "SAMModelLoader (segment anything)",
"_meta": {
"title": "SAMModelLoader (segment anything)"
}
},
"71:2": {
"inputs": {
"prompt": "cloth",
"threshold": 0.30000000000000004,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"25",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"71:3": {
"inputs": {
"images": [
"71:2",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
}
}
+913
View File
@@ -0,0 +1,913 @@
{
"3": {
"inputs": {
"seed": 133974548609577,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"17",
0
],
"negative": [
"17",
1
],
"latent_image": [
"17",
2
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"16",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"strength": 1.0000000000000002,
"strength_type": "multiply",
"conditioning": [
"11",
0
],
"style_model": [
"79",
0
],
"clip_vision_output": [
"20",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "Apply Style Model"
}
},
"11": {
"inputs": {
"guidance": 30,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"12": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"13": {
"inputs": {
"model": [
"75",
0
]
},
"class_type": "DifferentialDiffusion",
"_meta": {
"title": "Differential Diffusion"
}
},
"16": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"17": {
"inputs": {
"noise_mask": false,
"positive": [
"10",
0
],
"negative": [
"7",
0
],
"vae": [
"16",
0
],
"pixels": [
"27",
1
],
"mask": [
"27",
2
]
},
"class_type": "InpaintModelConditioning",
"_meta": {
"title": "InpaintModelConditioning"
}
},
"20": {
"inputs": {
"crop": "center",
"clip_vision": [
"21",
0
],
"image": [
"25",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP Vision Encode"
}
},
"21": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "Load CLIP Vision"
}
},
"22": {
"inputs": {
"image": "man_cloth.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"25": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"22",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"26": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"61",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"27": {
"inputs": {
"context_expand_pixels": 20,
"context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true,
"blur_mask_pixels": 10,
"invert_mask": false,
"blend_pixels": 16,
"rescale_algorithm": "bicubic",
"mode": "ranged size",
"force_width": 1024,
"force_height": 1024,
"rescale_factor": 1.0000000000000002,
"min_width": 512,
"min_height": 512,
"max_width": 1800,
"max_height": 1800,
"padding": 32,
"image": [
"42",
0
],
"mask": [
"30",
0
],
"optional_context_mask": [
"40",
0
]
},
"class_type": "InpaintCrop",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Crop node)"
}
},
"28": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"29": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"28",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"30": {
"inputs": {
"channel": "red",
"image": [
"43",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"34": {
"inputs": {
"rescale_algorithm": "bislerp",
"stitch": [
"27",
0
],
"inpainted_image": [
"8",
0
]
},
"class_type": "InpaintStitch",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Stitch node)"
}
},
"37": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"38",
0
],
"image2": [
"57",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"38": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"40": {
"inputs": {
"channel": "red",
"image": [
"37",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"42": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"25",
0
],
"image2": [
"26",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"43": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"59",
0
],
"image2": [
"29",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"45": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"57": {
"inputs": {
"brightness": -1,
"contrast": 0,
"saturation": 0,
"sharpness": 0,
"blur": 0,
"gaussian_blur": 0,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"26",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"59": {
"inputs": {
"brightness": -1,
"contrast": 1.0000000000000002,
"saturation": 1.0000000000000002,
"sharpness": 1.0000000000000002,
"blur": 0,
"gaussian_blur": 48.1,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"25",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"61": {
"inputs": {
"image": "微信图片_20250808213937_73.png"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"75": {
"inputs": {
"model_path": "svdq-int4-flux.1-fill-dev",
"cache_threshold": 0,
"attention": "nunchaku-fp16",
"cpu_offload": "auto",
"device_id": 0,
"data_type": "bfloat16",
"i2f_mode": "enabled"
},
"class_type": "NunchakuFluxDiTLoader",
"_meta": {
"title": "Nunchaku FLUX DiT Loader"
}
},
"79": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "Load Style Model"
}
},
"83": {
"inputs": {
"images": [
"29",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"84": {
"inputs": {
"images": [
"43",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"85": {
"inputs": {
"mask": [
"30",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"86": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskPreview+",
"_meta": {
"title": "🔧 Mask Preview"
}
},
"87": {
"inputs": {
"images": [
"38",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"88": {
"inputs": {
"images": [
"37",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"89": {
"inputs": {
"images": [
"57",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"90": {
"inputs": {
"images": [
"59",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"91": {
"inputs": {
"images": [
"27",
1
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"93": {
"inputs": {
"mask": [
"27",
2
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"94": {
"inputs": {
"value": 1536
},
"class_type": "PrimitiveInt",
"_meta": {
"title": "Int"
}
},
"95": {
"inputs": {
"detect_hand": "disable",
"detect_body": "enable",
"detect_face": "disable",
"resolution": 512,
"bbox_detector": "yolo_nas_m_fp16.onnx",
"pose_estimator": "dw-ll_ucoco_384.onnx",
"scale_stick_for_xinsr_cn": "disable",
"image": [
"61",
0
]
},
"class_type": "DWPreprocessor",
"_meta": {
"title": "DWPose Estimator"
}
},
"96": {
"inputs": {
"cloth_len": "拖地",
"line_len": 0.4000000000000001,
"cloth_short": true,
"width": 0,
"height": 0,
"left_right_line_width": 1,
"human_head2_yao_times": 2.5,
"more_clip": 0.1,
"kps": [
"95",
1
]
},
"class_type": "RenderPeopleKpsMask",
"_meta": {
"title": "My RenderPeopleKps Mask"
}
},
"98": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"99": {
"inputs": {
"width": [
"108",
0
],
"height": [
"107",
1
],
"x": [
"109",
0
],
"y": 0,
"image": [
"34",
0
]
},
"class_type": "ImageCrop",
"_meta": {
"title": "Image Crop"
}
},
"102": {
"inputs": {
"filename_prefix": "my_test_out",
"images": [
"99",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"104": {
"inputs": {
"image": [
"61",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"106": {
"inputs": {
"op": "Mul",
"a": [
"107",
1
],
"b": [
"104",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"107": {
"inputs": {
"image": [
"34",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"108": {
"inputs": {
"op": "Div",
"a": [
"106",
0
],
"b": [
"104",
1
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"109": {
"inputs": {
"op": "Sub",
"a": [
"107",
0
],
"b": [
"108",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"119": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"120": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"124": {
"inputs": {
"images": [
"95",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"128": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"71:1": {
"inputs": {
"model_name": "GroundingDINO_SwinT_OGC (694MB)"
},
"class_type": "GroundingDinoModelLoader (segment anything)",
"_meta": {
"title": "GroundingDinoModelLoader (segment anything)"
}
},
"71:0": {
"inputs": {
"model_name": "sam_vit_h (2.56GB)"
},
"class_type": "SAMModelLoader (segment anything)",
"_meta": {
"title": "SAMModelLoader (segment anything)"
}
},
"71:2": {
"inputs": {
"prompt": "cloth",
"threshold": 0.30000000000000004,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"25",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"71:3": {
"inputs": {
"images": [
"71:2",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
}
}
+913
View File
@@ -0,0 +1,913 @@
{
"3": {
"inputs": {
"seed": 48923133504876,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"17",
0
],
"negative": [
"17",
1
],
"latent_image": [
"17",
2
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"12",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"16",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"strength": 1.0000000000000002,
"strength_type": "multiply",
"conditioning": [
"11",
0
],
"style_model": [
"79",
0
],
"clip_vision_output": [
"20",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "Apply Style Model"
}
},
"11": {
"inputs": {
"guidance": 30,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"12": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"13": {
"inputs": {
"model": [
"75",
0
]
},
"class_type": "DifferentialDiffusion",
"_meta": {
"title": "Differential Diffusion"
}
},
"16": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"17": {
"inputs": {
"noise_mask": false,
"positive": [
"10",
0
],
"negative": [
"7",
0
],
"vae": [
"16",
0
],
"pixels": [
"27",
1
],
"mask": [
"27",
2
]
},
"class_type": "InpaintModelConditioning",
"_meta": {
"title": "InpaintModelConditioning"
}
},
"20": {
"inputs": {
"crop": "center",
"clip_vision": [
"21",
0
],
"image": [
"25",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP Vision Encode"
}
},
"21": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "Load CLIP Vision"
}
},
"22": {
"inputs": {
"image": "微信图片_20250810123345_95.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"25": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"22",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"26": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"61",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"27": {
"inputs": {
"context_expand_pixels": 20,
"context_expand_factor": 1.0000000000000002,
"fill_mask_holes": true,
"blur_mask_pixels": 10,
"invert_mask": false,
"blend_pixels": 16,
"rescale_algorithm": "bicubic",
"mode": "ranged size",
"force_width": 1024,
"force_height": 1024,
"rescale_factor": 1.0000000000000002,
"min_width": 512,
"min_height": 512,
"max_width": 1800,
"max_height": 1800,
"padding": 32,
"image": [
"42",
0
],
"mask": [
"30",
0
],
"optional_context_mask": [
"40",
0
]
},
"class_type": "InpaintCrop",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Crop node)"
}
},
"28": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"29": {
"inputs": {
"width": [
"94",
0
],
"height": [
"94",
0
],
"interpolation": "bicubic",
"method": "keep proportion",
"condition": "always",
"multiple_of": 0,
"image": [
"28",
0
]
},
"class_type": "ImageResize+",
"_meta": {
"title": "🔧 Image Resize"
}
},
"30": {
"inputs": {
"channel": "red",
"image": [
"43",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"34": {
"inputs": {
"rescale_algorithm": "bislerp",
"stitch": [
"27",
0
],
"inpainted_image": [
"8",
0
]
},
"class_type": "InpaintStitch",
"_meta": {
"title": "(OLD 💀, use the new ✂️ Inpaint Stitch node)"
}
},
"37": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"38",
0
],
"image2": [
"57",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"38": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskToImage",
"_meta": {
"title": "Convert Mask to Image"
}
},
"40": {
"inputs": {
"channel": "red",
"image": [
"37",
0
]
},
"class_type": "ImageToMask",
"_meta": {
"title": "Convert Image to Mask"
}
},
"42": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"25",
0
],
"image2": [
"26",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"43": {
"inputs": {
"direction": "right",
"match_image_size": true,
"image1": [
"59",
0
],
"image2": [
"29",
0
]
},
"class_type": "ImageConcanate",
"_meta": {
"title": "Image Concatenate"
}
},
"45": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"57": {
"inputs": {
"brightness": -1,
"contrast": 0,
"saturation": 0,
"sharpness": 0,
"blur": 0,
"gaussian_blur": 0,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"26",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"59": {
"inputs": {
"brightness": -1,
"contrast": 1.0000000000000002,
"saturation": 1.0000000000000002,
"sharpness": 1.0000000000000002,
"blur": 0,
"gaussian_blur": 48.1,
"edge_enhance": 0,
"detail_enhance": "false",
"image": [
"25",
0
]
},
"class_type": "Image Filter Adjustments",
"_meta": {
"title": "Image Filter Adjustments"
}
},
"61": {
"inputs": {
"image": "微信图片_20250809133614_84.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"75": {
"inputs": {
"model_path": "svdq-fp4_r32-flux.1-fill-dev.safetensors",
"cache_threshold": 0,
"attention": "nunchaku-fp16",
"cpu_offload": "auto",
"device_id": 0,
"data_type": "bfloat16",
"i2f_mode": "enabled"
},
"class_type": "NunchakuFluxDiTLoader",
"_meta": {
"title": "Nunchaku FLUX DiT Loader"
}
},
"79": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "Load Style Model"
}
},
"83": {
"inputs": {
"images": [
"29",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"84": {
"inputs": {
"images": [
"43",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"85": {
"inputs": {
"mask": [
"30",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"86": {
"inputs": {
"mask": [
"71:2",
1
]
},
"class_type": "MaskPreview+",
"_meta": {
"title": "🔧 Mask Preview"
}
},
"87": {
"inputs": {
"images": [
"38",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"88": {
"inputs": {
"images": [
"37",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"89": {
"inputs": {
"images": [
"57",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"90": {
"inputs": {
"images": [
"59",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"91": {
"inputs": {
"images": [
"27",
1
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"93": {
"inputs": {
"mask": [
"27",
2
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"94": {
"inputs": {
"value": 2048
},
"class_type": "PrimitiveInt",
"_meta": {
"title": "Int"
}
},
"95": {
"inputs": {
"detect_hand": "disable",
"detect_body": "enable",
"detect_face": "disable",
"resolution": 512,
"bbox_detector": "yolo_nas_m_fp16.onnx",
"pose_estimator": "dw-ll_ucoco_384.onnx",
"scale_stick_for_xinsr_cn": "disable",
"image": [
"61",
0
]
},
"class_type": "DWPreprocessor",
"_meta": {
"title": "DWPose Estimator"
}
},
"96": {
"inputs": {
"cloth_len": "腰",
"line_len": 0.4000000000000001,
"cloth_short": true,
"width": 0,
"height": 0,
"left_right_line_width": 1,
"human_head2_yao_times": 2.5,
"more_clip": 0.1,
"kps": [
"95",
1
]
},
"class_type": "RenderPeopleKpsMask",
"_meta": {
"title": "My RenderPeopleKps Mask"
}
},
"98": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"99": {
"inputs": {
"width": [
"108",
0
],
"height": [
"107",
1
],
"x": [
"109",
0
],
"y": 0,
"image": [
"34",
0
]
},
"class_type": "ImageCrop",
"_meta": {
"title": "Image Crop"
}
},
"102": {
"inputs": {
"filename_prefix": "my_test_out",
"images": [
"99",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"104": {
"inputs": {
"image": [
"61",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"106": {
"inputs": {
"op": "Mul",
"a": [
"107",
1
],
"b": [
"104",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"107": {
"inputs": {
"image": [
"34",
0
]
},
"class_type": "GetImageSize",
"_meta": {
"title": "Get Image Size"
}
},
"108": {
"inputs": {
"op": "Div",
"a": [
"106",
0
],
"b": [
"104",
1
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"109": {
"inputs": {
"op": "Sub",
"a": [
"107",
0
],
"b": [
"108",
0
]
},
"class_type": "CM_IntBinaryOperation",
"_meta": {
"title": "IntBinaryOperation"
}
},
"119": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"120": {
"inputs": {
"anything": [
"10",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"124": {
"inputs": {
"images": [
"95",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"128": {
"inputs": {
"mask": [
"96",
0
]
},
"class_type": "MaskPreview",
"_meta": {
"title": "MaskPreview"
}
},
"71:1": {
"inputs": {
"model_name": "GroundingDINO_SwinT_OGC (694MB)"
},
"class_type": "GroundingDinoModelLoader (segment anything)",
"_meta": {
"title": "GroundingDinoModelLoader (segment anything)"
}
},
"71:0": {
"inputs": {
"model_name": "sam_vit_h (2.56GB)"
},
"class_type": "SAMModelLoader (segment anything)",
"_meta": {
"title": "SAMModelLoader (segment anything)"
}
},
"71:2": {
"inputs": {
"prompt": "cloth",
"threshold": 0.30000000000000004,
"sam_model": [
"71:0",
0
],
"grounding_dino_model": [
"71:1",
0
],
"image": [
"25",
0
]
},
"class_type": "GroundingDinoSAMSegment (segment anything)",
"_meta": {
"title": "GroundingDinoSAMSegment (segment anything)"
}
},
"71:3": {
"inputs": {
"images": [
"71:2",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
}
}
+119
View File
@@ -0,0 +1,119 @@
import base64
#from openai import OpenAI
# client = OpenAI(
# #api_key="sk-6Fr1OWm8SJXseEtWjArObksjTr39P08HSNydgNFgsOewI0xp",
# api_key="sk-zLFhpbBQKWV4qohV4vD0AFR6Gaa7JwL0Q8zphh1CYFl2EqDM",
# base_url="https://www.chataiapi.com/v1",
# )
#https://ai.juguang.chat/console/topup
import requests
import json
import http.client
import json
import base64
import re
def save_base64_image_from_json(json_str, output_filename):
"""
从JSON字符串中提取base64图片数据并保存为文件
"""
try:
# 解析JSON
data = json.loads(json_str)
parts = data["candidates"][0]["content"]["parts"]
# 遍历parts找到包含inlineData的那个
base64_data = None
for part in parts:
if "inlineData" in part and "data" in part["inlineData"]:
base64_data = part["inlineData"]["data"]
break
if base64_data is None:
print("未找到包含图片数据的部分")
return False
# 清理可能的换行符和空格
base64_data = re.sub(r'\s+', '', base64_data)
# 解码base64数据
image_data = base64.b64decode(base64_data)
# 保存为文件
with open(output_filename, 'wb') as f:
f.write(image_data)
print(f"图片已成功保存为: {output_filename}")
return True
except Exception as e:
print(f"保存图片时发生错误: {e}")
return False
def image_to_base64(file_path, mime_type=None):
if mime_type is None:
extension = file_path.split('.')[-1].lower()
mime_types = {
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif',
'webp': 'image/webp',
'bmp': 'image/bmp'
}
mime_type = mime_types.get(extension, 'application/octet-stream')
# 读取文件内容并编码为Base64
with open(file_path, 'rb') as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
# 组合成Data URI格式
#return f"data:{mime_type};base64,{encoded_string}"
return encoded_string
conn = http.client.HTTPSConnection("ai.juguang.chat")
payload = json.dumps({
"contents": [
{
"parts": [
{
"text": "这是一张有人的图片"
},
{
"inline_data": {
"mime_type": "image/jpeg",
"data": image_to_base64("/home/xsl/code/ComfyUI/change_cloth/static/imgs/0b9014f9-14dc-4a97-9c99-642441b8c122.jpg")
}
},
{
"text": "这是另外一张有衣服,裤子或者裙子,和其他各种可以穿戴在身上物品的图片"
},
{
"inline_data": {
"mime_type": "image/jpeg",
"data": image_to_base64("/home/xsl/code/ComfyUI/change_cloth/cloth_suit.jpg")
}
},
{
"text": "给第一张图片的人物,换上第二张图片的衣服和配饰"
}
]
}
]
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk-zLFhpbBQKWV4qohV4vD0AFR6Gaa7JwL0Q8zphh1CYFl2EqDM'
}
conn.request("POST", "/v1beta/models/gemini-2.5-flash-image-preview:generateContent", payload, headers)
res = conn.getresponse()
data = res.read()
decode_str = data.decode("utf-8")
# 调用函数保存图片
save_base64_image_from_json(decode_str, "out_image.png")
print(decode_str)
+258
View File
@@ -0,0 +1,258 @@
import os
import requests
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
import logging
from datetime import datetime
import threading
import queue
import uuid
import time
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_FOLDER = os.path.join(APP_ROOT, 'static')
app = Flask(__name__, static_folder=STATIC_FOLDER, static_url_path='/static')
CORS(app)
CHANGE_APP_BASE_URL = "http://127.0.0.1:28889"
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def log_message(msg):
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {msg}")
logger.info(msg)
class DualQueueProcessor:
def __init__(self):
self.normal_lock = threading.Lock()
self.kuzi_lock = threading.Lock()
self.normal_queue = queue.Queue()
self.kuzi_queue = queue.Queue()
self.normal_processing = 0
self.kuzi_processing = 0
self.normal_total = 0
self.kuzi_total = 0
self.stats_lock = threading.Lock()
self._start_workers()
def _start_workers(self):
normal_worker = threading.Thread(target=self._process_normal_queue, daemon=True)
normal_worker.start()
kuzi_worker = threading.Thread(target=self._process_kuzi_queue, daemon=True)
kuzi_worker.start()
log_message("Dual queue workers started: normal_queue and kuzi_queue")
def _process_normal_queue(self):
while True:
task_id, data, result_event, result_container = self.normal_queue.get()
log_message(f"[Normal Queue] Processing task {task_id}, queue_size={self.normal_queue.qsize()}")
try:
response = requests.post(
f"{CHANGE_APP_BASE_URL}/change_cloth_base64",
json=data,
timeout=600
)
result_container['status_code'] = response.status_code
result_container['json'] = response.json()
result_container['success'] = True
log_message(f"[Normal Queue] Task {task_id} completed with status {response.status_code}")
except requests.exceptions.Timeout:
result_container['success'] = False
result_container['error'] = "Request timeout"
log_message(f"[Normal Queue] Task {task_id} timeout")
except requests.exceptions.RequestException as e:
result_container['success'] = False
result_container['error'] = str(e)
log_message(f"[Normal Queue] Task {task_id} error: {str(e)}")
finally:
result_event.set()
self.normal_queue.task_done()
def _process_kuzi_queue(self):
while True:
task_id, data, result_event, result_container = self.kuzi_queue.get()
log_message(f"[Kuzi Queue] Processing task {task_id}, queue_size={self.kuzi_queue.qsize()}")
try:
response = requests.post(
f"{CHANGE_APP_BASE_URL}/change_cloth_base64",
json=data,
timeout=600
)
result_container['status_code'] = response.status_code
result_container['json'] = response.json()
result_container['success'] = True
log_message(f"[Kuzi Queue] Task {task_id} completed with status {response.status_code}")
except requests.exceptions.Timeout:
result_container['success'] = False
result_container['error'] = "Request timeout"
log_message(f"[Kuzi Queue] Task {task_id} timeout")
except requests.exceptions.RequestException as e:
result_container['success'] = False
result_container['error'] = str(e)
log_message(f"[Kuzi Queue] Task {task_id} error: {str(e)}")
finally:
result_event.set()
self.kuzi_queue.task_done()
def submit_request(self, data):
has_kuzi = data.get('kuzi_img') is not None and data.get('kuzi_img') != ''
task_id = str(uuid.uuid4())[:8]
result_event = threading.Event()
result_container = {'success': False}
if has_kuzi:
with self.stats_lock:
self.kuzi_total += 1
queue_position = self.kuzi_queue.qsize() + 1
self.kuzi_queue.put((task_id, data, result_event, result_container))
log_message(f"[Kuzi Queue] Task {task_id} submitted, position={queue_position}")
queue_name = "kuzi"
else:
with self.stats_lock:
self.normal_total += 1
queue_position = self.normal_queue.qsize() + 1
self.normal_queue.put((task_id, data, result_event, result_container))
log_message(f"[Normal Queue] Task {task_id} submitted, position={queue_position}")
queue_name = "normal"
return task_id, result_event, result_container, queue_name, queue_position
def get_stats(self):
with self.stats_lock:
return {
"normal_queue_size": self.normal_queue.qsize(),
"kuzi_queue_size": self.kuzi_queue.qsize(),
"normal_total": self.normal_total,
"kuzi_total": self.kuzi_total
}
dual_queue = DualQueueProcessor()
@app.route('/')
def index():
return send_from_directory(STATIC_FOLDER, 'index.html')
@app.route('/health', methods=['GET'])
def health():
return jsonify({"status": "ok", "service": "change_cloth_proxy"})
@app.route('/queue_stats', methods=['GET'])
def queue_stats():
stats = dual_queue.get_stats()
return jsonify({
"ret": 0,
"msg": "success",
"data": stats
})
@app.route('/change_cloth', methods=['POST'])
def change_cloth():
log_message("change_cloth called")
data = request.get_json()
if not data:
return jsonify({"ret": -1, "state": -1, "msg": "No JSON data provided"}), 400
required_fields = ["human_url", "cloth_url", "output_format"]
for field in required_fields:
if field not in data:
return jsonify({"ret": -1, "state": -1, "msg": f"Missing required field: {field}"}), 400
log_message(f"Forwarding change_cloth request: human_url={data.get('human_url')}, cloth_url={data.get('cloth_url')}")
try:
response = requests.post(
f"{CHANGE_APP_BASE_URL}/change_cloth",
json=data,
timeout=600
)
log_message(f"change_cloth response status: {response.status_code}")
return jsonify(response.json()), response.status_code
except requests.exceptions.Timeout:
log_message("change_cloth request timeout")
return jsonify({"ret": -1, "state": -1, "msg": "Request timeout"}), 504
except requests.exceptions.RequestException as e:
log_message(f"change_cloth request error: {str(e)}")
return jsonify({"ret": -1, "state": -1, "msg": f"Request failed: {str(e)}"}), 500
@app.route('/change_cloth_base64', methods=['POST'])
def change_cloth_base64():
log_message("change_cloth_base64 called")
data = request.get_json()
if not data:
return jsonify({"ret": -1, "state": -1, "msg": "No JSON data provided"}), 400
required_fields = ["human_img", "cloth_img", "output_format"]
for field in required_fields:
if field not in data:
return jsonify({"ret": -1, "state": -1, "msg": f"Missing required field: {field}"}), 400
has_kuzi = data.get('kuzi_img') is not None and data.get('kuzi_img') != ''
queue_type = "kuzi" if has_kuzi else "normal"
task_id, result_event, result_container, queue_name, queue_position = dual_queue.submit_request(data)
log_message(f"Task {task_id} queued in {queue_name} queue, position={queue_position}, waiting for result...")
if result_event.wait(timeout=610):
if result_container.get('success'):
log_message(f"Task {task_id} returned successfully")
return jsonify(result_container['json']), result_container['status_code']
else:
error_msg = result_container.get('error', 'Unknown error')
log_message(f"Task {task_id} failed: {error_msg}")
return jsonify({"ret": -1, "state": -1, "msg": error_msg}), 500
else:
log_message(f"Task {task_id} timed out waiting in queue")
return jsonify({"ret": -1, "state": -1, "msg": "Queue timeout"}), 504
@app.route('/do_change_cloth', methods=['POST'])
def do_change_cloth():
log_message("do_change_cloth called")
data = request.get_json()
if not data:
return jsonify({"ret": -1, "state": -1, "msg": "No JSON data provided"}), 400
required_fields = ["human_url", "cloth_url", "output_format"]
for field in required_fields:
if field not in data:
return jsonify({"ret": -1, "state": -1, "msg": f"Missing required field: {field}"}), 400
log_message(f"Forwarding do_change_cloth request: human_url={data.get('human_url')}, cloth_url={data.get('cloth_url')}")
try:
response = requests.post(
f"{CHANGE_APP_BASE_URL}/do_change_cloth",
json=data,
timeout=600
)
log_message(f"do_change_cloth response status: {response.status_code}")
return jsonify(response.json()), response.status_code
except requests.exceptions.Timeout:
log_message("do_change_cloth request timeout")
return jsonify({"ret": -1, "state": -1, "msg": "Request timeout"}), 504
except requests.exceptions.RequestException as e:
log_message(f"do_change_cloth request error: {str(e)}")
return jsonify({"ret": -1, "state": -1, "msg": f"Request failed: {str(e)}"}), 500
if __name__ == '__main__':
log_message(f"Starting change_cloth_proxy service on port 28888, forwarding to {CHANGE_APP_BASE_URL}")
app.run(host="0.0.0.0", port=28888, debug=False, threaded=True)
+313
View File
@@ -0,0 +1,313 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>服装更换工具</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
h1 {
text-align: center;
color: #333;
}
.image-upload-container {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.image-upload-box {
width: 48%;
border: 2px dashed #ccc;
padding: 15px;
text-align: center;
border-radius: 5px;
}
.image-upload-box h3 {
margin-top: 0;
}
.image-preview {
max-width: 100%;
max-height: 300px;
margin-top: 10px;
display: none;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
display: block;
margin: 20px auto;
}
button:hover {
background-color: #45a049;
}
#result {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 4px;
display: none;
}
#loading {
text-align: center;
display: none;
margin: 20px 0;
}
.spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 2s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error {
color: red;
}
.option-box {
margin: 15px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.option-box label {
display: block;
margin-bottom: 10px;
}
.cloth-len-select {
margin: 15px 0;
}
.cloth-len-select label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.cloth-len-select select {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
</style>
</head>
<body>
<h1>服装更换工具</h1>
<div class="image-upload-container">
<div class="image-upload-box">
<h3>人体图片</h3>
<input type="file" id="humanInput" accept="image/*">
<img id="humanPreview" class="image-preview" alt="人体图片预览">
</div>
<div class="image-upload-box">
<h3>衣服图片</h3>
<input type="file" id="clothInput" accept="image/*">
<img id="clothPreview" class="image-preview" alt="衣服图片预览">
</div>
</div>
<div class="image-upload-container">
<div class="image-upload-box">
<h3>裤子图片</h3>
<input type="file" id="kuziInput" accept="image/*">
<img id="kuziPreview" class="image-preview" alt="裤子图片预览">
</div>
<div class="cloth-len-select">
<label for="clothLenSelect">选择服装长度:</label>
<select id="clothLenSelect">
<option value="胸"></option>
<option value="腰"></option>
<option value="跨"></option>
<option value="大腿">大腿</option>
<option value="膝盖">膝盖</option>
<option value="小腿">小腿</option>
<option value="脚踝">脚踝</option>
<option value="拖地">拖地</option>
</select>
</div>
</div>
<div class="option-box">
<label>
<input type="checkbox" id="no2Checkbox"> 设置 no2 不要两步(一步完成)
</label>
<br>
<label>
<input type="checkbox" id="tuodiCheckbox"> 设置 tuodi(拖地)
</label>
<br>
<label>
<input type="checkbox" id="suitCheckbox"> 设置 suit(套装)
</label>
</div>
<button id="submitBtn">提交处理</button>
<div id="loading">
<div class="spinner"></div>
<p>正在处理中,请稍候...</p>
</div>
<div id="result"></div>
<script>
document.getElementById('humanInput').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const img = document.getElementById('humanPreview');
img.src = event.target.result;
img.style.display = 'block';
};
reader.readAsDataURL(file);
}
});
document.getElementById('clothInput').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const img = document.getElementById('clothPreview');
img.src = event.target.result;
img.style.display = 'block';
};
reader.readAsDataURL(file);
}
});
document.getElementById('kuziInput').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const img = document.getElementById('kuziPreview');
img.src = event.target.result;
img.style.display = 'block';
};
reader.readAsDataURL(file);
}
});
document.getElementById('submitBtn').addEventListener('click', function() {
const humanFile = document.getElementById('humanInput').files[0];
const clothFile = document.getElementById('clothInput').files[0];
const kuziFile = document.getElementById('kuziInput').files[0];
const no2 = document.getElementById("no2Checkbox").checked;
const tuodi = document.getElementById("tuodiCheckbox").checked;
const suit = document.getElementById("suitCheckbox").checked;
const clothLen = document.getElementById("clothLenSelect").value;
if (!humanFile || !clothFile) {
alert('请同时选择人体图片和衣服图片!');
return;
}
document.getElementById('loading').style.display = 'block';
document.getElementById('result').style.display = 'none';
Promise.all([
readFileAsDataURL(humanFile),
readFileAsDataURL(clothFile),
kuziFile ? readFileAsDataURL(kuziFile) : Promise.resolve(null)
]).then(([humanDataURL, clothDataURL, kuziDataURL]) => {
const data = {
human_img: humanDataURL,
cloth_img: clothDataURL,
output_format: "url",
no2: no2,
tuodi: tuodi,
suit: suit,
cloth_len: clothLen
};
if(kuziDataURL)
{
data.kuzi_img = kuziDataURL;
}
console.log("准备发送的数据:", data);
fetch('/change_cloth_base64', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
return response.json();
})
.then(data => {
document.getElementById('loading').style.display = 'none';
const resultDiv = document.getElementById('result');
if (data.url) {
resultDiv.innerHTML = `
<h3>处理结果</h3>
<p>处理成功!点击查看结果:</p>
<a href="${data.url}" target="_blank">${data.url}</a>
<p><img src="${data.url}" style="max-width: 100%; margin-top: 10px;"></p>
<a href="${data.first_url}" target="_blank">${data.url}</a>
<p><img src="${data.first_url}" style="max-width: 100%; margin-top: 10px;"></p>
<a href="${data.second_url}" target="_blank">${data.url}</a>
<p><img src="${data.second_url}" style="max-width: 100%; margin-top: 10px;"></p>
`;
} else {
resultDiv.innerHTML = `
<h3>处理结果</h3>
<p class="error">处理完成,但未返回预期的URL</p>
<p>返回数据:</p>
<pre>${JSON.stringify(data, null, 2)}</pre>
`;
}
resultDiv.style.display = 'block';
})
.catch(error => {
console.error('Error:', error);
document.getElementById('loading').style.display = 'none';
document.getElementById('result').innerHTML = `
<h3 class="error">错误</h3>
<p>处理过程中出现错误:${error.message}</p>
<p>请检查控制台获取更多信息</p>
`;
document.getElementById('result').style.display = 'block';
});
});
});
function readFileAsDataURL(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
reader.readAsDataURL(file);
});
}
</script>
</body>
</html>
File diff suppressed because it is too large Load Diff
+1031
View File
File diff suppressed because it is too large Load Diff
+68 -1
View File
@@ -1,6 +1,73 @@
import cv2 import cv2
import mediapipe as mp import mediapipe as mp
async def listen_node_output(prompt_id, target_node_id):
uri = "ws://localhost:8188/ws"
async with websockets.connect(uri) as websocket:
await websocket.send(json.dumps({"prompt_id": prompt_id}))
while True:
message = await websocket.recv()
# 1. 处理二进制数据
if isinstance(message, bytes):
try:
message = message.decode("utf-8")
except UnicodeDecodeError:
print(f"[{datetime.now().strftime('%H:%M:%S')}] 收到二进制数据 (长度: {len(message)} bytes)")
continue
# 2. 解析JSON
try:
data = json.loads(message)
print(f"cur data {data}")
except json.JSONDecodeError:
print(f"[{datetime.now().strftime('%H:%M:%S')}] 非JSON数据: {message[:100]}...")
continue
if data.get("type") == "progress":
pdata = data.get('data', {})
print(f"cur progress {pdata}")
# if value >= max:
# return f"finished value:{value} max:{max}"
if data.get("type") == "progress_state":
nodes = data.get('data', {}).get('nodes', {})
for node in nodes:
if node.get("state", None) != 'finished':
print(f"progress_state node:{node}")
# 3. 输出运行状态
if data.get("type") == "status":
print(f"[{datetime.now().strftime('%H:%M:%S')}] 系统状态: {data.get('data', {}).get('status', {})}")
status = data.get('data', {}).get('status', None)
print(f"statue:{status}")
if status:
exec_info = status.get('exec_info', None)
print(f"exec_info:{exec_info}")
if exec_info:
queue_remaining = exec_info.get('queue_remaining', None)
print(f"queue_remaining:{queue_remaining}")
if queue_remaining == 0:
return "process end"
continue
if data.get("type") == "executing":
node_id = data.get("data", {}).get("node")
progress = data.get("data", {}).get("progress", 0)
print(f"[{datetime.now().strftime('%H:%M:%S')}] 正在执行节点 {node_id} (进度: {progress:.0%})")
# 4. 目标节点完成
if data.get("type") == "executed" and data.get("data", {}).get("node") == target_node_id:
output = data.get("data", {}).get("output")
print(f"[{datetime.now().strftime('%H:%M:%S')}] 节点 {target_node_id} 完成!")
return output
# output = asyncio.run(listen_node_output(prompt_id, "104"))
# print("最终输出:", output)
# def is_thigh_visible(image_path): # def is_thigh_visible(image_path):
# # 初始化MediaPipe Pose模型 # # 初始化MediaPipe Pose模型
# mp_pose = mp.solutions.pose # mp_pose = mp.solutions.pose
@@ -36,4 +103,4 @@ import mediapipe as mp
# return left_thigh_visible and right_thigh_visible # return left_thigh_visible and right_thigh_visible
# print(is_thigh_visible("/home/szlc/code/ComfyUI/change_cloth/static/imgs/fc74eded_00001_.jpg")) # print(is_thigh_visible("/home/xsl/code/ComfyUI/change_cloth/static/imgs/fc74eded_00001_.jpg"))
+18 -1
View File
@@ -4,7 +4,7 @@ import logging
QUEUE_NAME = 'task_queue' QUEUE_NAME = 'task_queue'
# 配置 # 配置
REDIS_HOST = '127.0.0.1' REDIS_HOST = '127.0.0.1'#'192.168.101.118'
REDIS_PORT = 6379 REDIS_PORT = 6379
REDIS_DB = 0 REDIS_DB = 0
DEFAULT_TIMEOUT = (60*20) DEFAULT_TIMEOUT = (60*20)
@@ -37,6 +37,23 @@ console_handler.setFormatter(console_formatter)
logger.addHandler(file_handler) logger.addHandler(file_handler)
logger.addHandler(console_handler) logger.addHandler(console_handler)
selfComputer = "5090"
if selfComputer == "5090":
change_tuodi_input = 'change_tuodi_input_api.json'
change_only_name = "change_new_only_change.json"
change_with_add_cloth = "change_new_debug_api.json"
xiezhen_name = "xiezhen-0812-40s_api.json"
base64_test_port = 28889
else:
change_tuodi_input = 'change_tuodi_input_3090_api.json'
change_only_name = "change_new_only_3090.json"
change_with_add_cloth = "change_new_3090_api.json"
xiezhen_name = "xiezhen-0812-40s_api.json"
base64_test_port = 18888
def acquire_lock(redis_client, lock_name): def acquire_lock(redis_client, lock_name):
lock = Lock( lock = Lock(
redis_client, redis_client,
+212
View File
@@ -0,0 +1,212 @@
{
"6": {
"inputs": {
"text": "Using this elegant style, create a portrait of a swan wearing a pearl tiara and lace collar, maintaining the same refined quality and soft color tones.",
"clip": [
"38",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"31",
0
],
"vae": [
"39",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"31": {
"inputs": {
"seed": 331754788447825,
"steps": 20,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"37",
0
],
"positive": [
"35",
0
],
"negative": [
"135",
0
],
"latent_image": [
"124",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"35": {
"inputs": {
"guidance": 2.5,
"conditioning": [
"177",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"37": {
"inputs": {
"unet_name": "flux1-dev-kontext_fp8_scaled.safetensors",
"weight_dtype": "default"
},
"class_type": "UNETLoader",
"_meta": {
"title": "Load Diffusion Model"
}
},
"38": {
"inputs": {
"clip_name1": "clip_l.safetensors",
"clip_name2": "t5xxl_fp8_e4m3fn_scaled.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"39": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"42": {
"inputs": {
"image": [
"146",
0
]
},
"class_type": "FluxKontextImageScale",
"_meta": {
"title": "FluxKontextImageScale"
}
},
"124": {
"inputs": {
"pixels": [
"42",
0
],
"vae": [
"39",
0
]
},
"class_type": "VAEEncode",
"_meta": {
"title": "VAE Encode"
}
},
"135": {
"inputs": {
"conditioning": [
"6",
0
]
},
"class_type": "ConditioningZeroOut",
"_meta": {
"title": "ConditioningZeroOut"
}
},
"136": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"142": {
"inputs": {
"image": "ComfyUI_00441_.png [output]",
"refresh": "refresh"
},
"class_type": "LoadImageOutput",
"_meta": {
"title": "Load Image (from Outputs)"
}
},
"146": {
"inputs": {
"direction": "right",
"match_image_size": true,
"spacing_width": 0,
"spacing_color": "white",
"image1": [
"142",
0
]
},
"class_type": "ImageStitch",
"_meta": {
"title": "Image Stitch"
}
},
"173": {
"inputs": {
"images": [
"42",
0
]
},
"class_type": "PreviewImage",
"_meta": {
"title": "Preview Image"
}
},
"177": {
"inputs": {
"conditioning": [
"6",
0
],
"latent": [
"124",
0
]
},
"class_type": "ReferenceLatent",
"_meta": {
"title": "ReferenceLatent"
}
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

+18 -16
View File
@@ -56,7 +56,7 @@ def takeoff_cloth_first(human_name):
if queue["queue_running"] or queue["queue_pending"]: if queue["queue_running"] or queue["queue_pending"]:
return None, "cur gpu is busy" return None, "cur gpu is busy"
with open('/home/szlc/code/ComfyUI/change_cloth/change_new.json', 'r', encoding='utf-8') as file: with open('/home/xsl/code/ComfyUI/change_cloth/change_new.json', 'r', encoding='utf-8') as file:
prompt_text = file.read() prompt_text = file.read()
prompt = json.loads(prompt_text) prompt = json.loads(prompt_text)
@@ -122,15 +122,15 @@ def change(human_name, cloth_name, c_width, c_height, cloth_url, is_generated):
return None, f"takeoff_cloth_first error {human_name}" return None, f"takeoff_cloth_first error {human_name}"
else: else:
human_name = takeoff_file_name human_name = takeoff_file_name
takeoff_file_path_name = os.path.join('/home/szlc/code/ComfyUI/output', takeoff_file_name) takeoff_file_path_name = os.path.join('/home/xsl/code/ComfyUI/output', takeoff_file_name)
takeoff_file_path_name_input = os.path.join('/home/szlc/code/ComfyUI/input', takeoff_file_name) takeoff_file_path_name_input = os.path.join('/home/xsl/code/ComfyUI/input', takeoff_file_name)
shutil.copy(takeoff_file_path_name, takeoff_file_path_name_input) shutil.copy(takeoff_file_path_name, takeoff_file_path_name_input)
queue = requests.get("http://localhost:8188/queue").json() queue = requests.get("http://localhost:8188/queue").json()
if queue["queue_running"] or queue["queue_pending"]: if queue["queue_running"] or queue["queue_pending"]:
return None, "cur gpu is busy" return None, "cur gpu is busy"
with open('/home/szlc/code/ComfyUI/change_cloth/change_new.json', 'r', encoding='utf-8') as file: with open('/home/xsl/code/ComfyUI/change_cloth/change_new.json', 'r', encoding='utf-8') as file:
prompt_text = file.read() prompt_text = file.read()
prompt = json.loads(prompt_text) prompt = json.loads(prompt_text)
@@ -207,13 +207,13 @@ def save_base64_image(base64_str, prefix):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
unique_id = str(uuid.uuid4())[:8] unique_id = str(uuid.uuid4())[:8]
filename = f"{prefix}_{timestamp}_{unique_id}{file_ext}" filename = f"{prefix}_{timestamp}_{unique_id}{file_ext}"
filepath = os.path.join('/home/szlc/code/ComfyUI/change_cloth/static/imgs', filename) filepath = os.path.join('/home/xsl/code/ComfyUI/change_cloth/static/imgs', filename)
# 解码并保存图片 # 解码并保存图片
with open(filepath, 'wb') as f: with open(filepath, 'wb') as f:
f.write(base64.b64decode(data)) f.write(base64.b64decode(data))
input_filepath = os.path.join('/home/szlc/code/ComfyUI/input', filename) input_filepath = os.path.join('/home/xsl/code/ComfyUI/input', filename)
# 解码并保存图片 # 解码并保存图片
with open(input_filepath, 'wb') as f: with open(input_filepath, 'wb') as f:
f.write(base64.b64decode(data)) f.write(base64.b64decode(data))
@@ -255,10 +255,10 @@ def image_to_base64(file_path, mime_type=None):
def upload_to_oss(image_path, object_name=None): def upload_to_oss(image_path, object_name=None):
# 配置信息(替换为你的实际信息) # 配置信息(替换为你的实际信息)
access_key_id = 'LTAI5tB9t2RH6f1drSLvVLLZ' access_key_id = 'LTAI5tGp1sLzedqxihcNC1eb'
access_key_secret = '91uzPI1RAFHN7n3Y6TJDGFP8w0dG1R' access_key_secret = 'IFZE1b8YYreCP6zfA6GaZ9uBT678qO'
endpoint = 'oss-cn-beijing.aliyuncs.com' # 替换为你的Endpoint endpoint = 'oss-cn-beijing.aliyuncs.com' # 替换为你的Endpoint
bucket_name = 'llyz' bucket_name = 'xiangsilian'
# 创建Bucket实例 # 创建Bucket实例
auth = oss2.Auth(access_key_id, access_key_secret) auth = oss2.Auth(access_key_id, access_key_secret)
@@ -286,21 +286,21 @@ def upload_to_oss(image_path, object_name=None):
def process_change_cloth(human_filename, cloth_filename, output_format, img_url, is_generated): def process_change_cloth(human_filename, cloth_filename, output_format, img_url, is_generated):
w,h = get_image_dimensions(f'/home/szlc/code/ComfyUI/input/{human_filename}') w,h = get_image_dimensions(f'/home/xsl/code/ComfyUI/input/{human_filename}')
out_put_name, msg = change(human_filename, cloth_filename, w, h, img_url, is_generated) out_put_name, msg = change(human_filename, cloth_filename, w, h, img_url, is_generated)
if out_put_name == None: if out_put_name == None:
print(f'Failed to change cloth {msg}') print(f'Failed to change cloth {msg}')
return jsonify({"ret":-1, 'msg': f'Failed to change cloth {msg}'}), 200 return jsonify({"ret":-1, 'msg': f'Failed to change cloth {msg}'}), 200
image = Image.open(f'/home/szlc/code/ComfyUI/output/{out_put_name}') image = Image.open(f'/home/xsl/code/ComfyUI/output/{out_put_name}')
jpg_name = out_put_name.replace(".png", ".jpg") jpg_name = out_put_name.replace(".png", ".jpg")
jpg_path_name = f'/home/szlc/code/ComfyUI/change_cloth/static/imgs/{jpg_name}' jpg_path_name = f'/home/xsl/code/ComfyUI/change_cloth/static/imgs/{jpg_name}'
image.save(jpg_path_name, quality=95) image.save(jpg_path_name, quality=95)
upload_to_oss(jpg_path_name, jpg_name) # 第二个参数可选,指定OSS上的路径 upload_to_oss(jpg_path_name, jpg_name) # 第二个参数可选,指定OSS上的路径
https_url = f'https://llyz.oss-cn-beijing.aliyuncs.com/{jpg_name}' https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/{jpg_name}'
print(f"生成的HTTPS URL: {https_url}") print(f"生成的HTTPS URL: {https_url}")
if 'base64' in output_format: if 'base64' in output_format:
@@ -347,7 +347,7 @@ def change_cloth_base64():
if not cloth_filename: if not cloth_filename:
return jsonify({"ret":-1, 'msg': 'Failed to save cloth image'}), 500 return jsonify({"ret":-1, 'msg': 'Failed to save cloth image'}), 500
img_url = f"http://112.126.94.241:18888/static/imgs/{cloth_filename}" img_url = f"http://117.50.44.174:18888/static/imgs/{cloth_filename}"
return process_change_cloth(human_filename, cloth_filename, output_format, img_url, is_generated) return process_change_cloth(human_filename, cloth_filename, output_format, img_url, is_generated)
@@ -376,13 +376,13 @@ def save_image_from_url(image_url):
# 获取原始图片格式 # 获取原始图片格式
ext = get_file_extension(image_url) ext = get_file_extension(image_url)
filename = f"{uuid.uuid4()}{ext}" filename = f"{uuid.uuid4()}{ext}"
filepath = os.path.join('/home/szlc/code/ComfyUI/change_cloth/static/imgs', filename) filepath = os.path.join('/home/xsl/code/ComfyUI/change_cloth/static/imgs', filename)
with open(filepath, "wb") as f: with open(filepath, "wb") as f:
for chunk in response.iter_content(1024): for chunk in response.iter_content(1024):
f.write(chunk) f.write(chunk)
input_filepath = os.path.join('/home/szlc/code/ComfyUI/input', filename) input_filepath = os.path.join('/home/xsl/code/ComfyUI/input', filename)
shutil.copy(filepath, input_filepath) shutil.copy(filepath, input_filepath)
return filename return filename
@@ -394,6 +394,7 @@ def save_image_from_url(image_url):
def change_cloth(): def change_cloth():
"""从 URL 下载图片""" """从 URL 下载图片"""
data = request.json data = request.json
print(f"change_cloth data: {data}")
is_generated = data.get("is_generated") is_generated = data.get("is_generated")
# if not is_generated: # if not is_generated:
@@ -406,6 +407,7 @@ def change_cloth():
if not human_url: if not human_url:
return jsonify({"error": "Missing 'human_url' parameter"}), 400 return jsonify({"error": "Missing 'human_url' parameter"}), 400
human_filename = save_image_from_url(human_url) human_filename = save_image_from_url(human_url)
if not human_filename: if not human_filename:
return jsonify({"error": "Failed to download or save human image"}), 500 return jsonify({"error": "Failed to download or save human image"}), 500
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+5 -5
View File
@@ -2,10 +2,10 @@ import oss2
def upload_to_oss(image_path, object_name=None): def upload_to_oss(image_path, object_name=None):
# 配置信息(替换为你的实际信息) # 配置信息(替换为你的实际信息)
access_key_id = 'LTAI5tB9t2RH6f1drSLvVLLZ' access_key_id = 'LTAI5tGp1sLzedqxihcNC1eb'
access_key_secret = '91uzPI1RAFHN7n3Y6TJDGFP8w0dG1R' access_key_secret = 'IFZE1b8YYreCP6zfA6GaZ9uBT678qO'
endpoint = 'oss-cn-beijing.aliyuncs.com' # 替换为你的Endpoint endpoint = 'oss-cn-beijing.aliyuncs.com' # 替换为你的Endpoint
bucket_name = 'llyz' bucket_name = 'xiangsilian'
# 创建Bucket实例 # 创建Bucket实例
auth = oss2.Auth(access_key_id, access_key_secret) auth = oss2.Auth(access_key_id, access_key_secret)
@@ -32,7 +32,7 @@ def upload_to_oss(image_path, object_name=None):
return None return None
# 使用示例 # 使用示例
image_path = '/home/szlc/code/ComfyUI/change_cloth/girl8010.jpg' # 本地图片路径 image_path = '/home/xsl/code/ComfyUI/change_cloth/girl8010.jpg' # 本地图片路径
upload_to_oss(image_path, 'girl8011.jpg') # 第二个参数可选,指定OSS上的路径 upload_to_oss(image_path, 'girl8011.jpg') # 第二个参数可选,指定OSS上的路径
https_url = f'https://llyz.oss-cn-beijing.aliyuncs.com/girl8011.jpg' https_url = f'https://xiangsilian.oss-cn-beijing.aliyuncs.com/girl8011.jpg'
print(f"生成的HTTPS URL: {https_url}") print(f"生成的HTTPS URL: {https_url}")
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

+186
View File
@@ -0,0 +1,186 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片处理工具</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
.container {
display: flex;
flex-direction: column;
gap: 20px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
label {
font-weight: bold;
}
input[type="file"], input[type="text"] {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 10px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #45a049;
}
.preview {
margin-top: 20px;
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.preview-item {
display: flex;
flex-direction: column;
align-items: center;
}
.preview-item img {
max-width: 200px;
max-height: 200px;
border: 1px solid #ddd;
margin-top: 10px;
}
#status {
margin-top: 20px;
padding: 10px;
border-radius: 4px;
}
.success {
background-color: #dff0d8;
color: #3c763d;
}
.error {
background-color: #f2dede;
color: #a94442;
}
</style>
</head>
<body>
<h1>图片处理工具</h1>
<div class="container">
<form id="imageForm">
<div class="form-group">
<label for="fileUpload">上传图片:</label>
<input type="file" id="fileUpload" name="file" accept="image/*" required>
<div class="preview">
<div class="preview-item">
<span>上传的图片预览:</span>
<img id="uploadPreview" src="#" alt="上传的图片预览" style="display: none;">
</div>
</div>
</div>
<div class="form-group">
<label for="clothImgUrl">服装图片URL:</label>
<input type="text" id="clothImgUrl" name="cloth_img"
value="http://117.50.44.174:18888/static/imgs/cloth_20250713_092536_279335d2.jpg"
placeholder="输入服装图片的URL" required>
<div class="preview">
<div class="preview-item">
<span>URL图片预览:</span>
<img id="urlPreview" src="http://117.50.44.174:18888/static/imgs/cloth_20250713_092536_279335d2.jpg"
alt="URL图片预览" onerror="this.style.display='none'">
</div>
</div>
</div>
<button type="submit">提交处理</button>
</form>
<div id="status"></div>
</div>
<script>
// 上传图片预览
document.getElementById('fileUpload').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const preview = document.getElementById('uploadPreview');
preview.src = event.target.result;
preview.style.display = 'block';
};
reader.readAsDataURL(file);
}
});
// URL图片预览
document.getElementById('clothImgUrl').addEventListener('input', function(e) {
const url = e.target.value;
if (url) {
const preview = document.getElementById('urlPreview');
preview.src = url;
preview.style.display = 'block';
// 检查图片是否能加载
preview.onerror = function() {
preview.alt = "无法加载图片";
preview.src = "";
};
}
});
// 表单提交
document.getElementById('imageForm').addEventListener('submit', function(e) {
e.preventDefault();
const statusDiv = document.getElementById('status');
statusDiv.textContent = "正在提交...";
statusDiv.className = "";
const formData = new FormData(this);
const apiUrl = "http://117.50.44.174:19001/process-image";
fetch(apiUrl, {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应不正常');
}
return response.json();
})
.then(data => {
statusDiv.textContent = "提交成功!";
statusDiv.className = "success";
console.log("成功:", data);
})
.catch(error => {
statusDiv.textContent = "提交失败: " + error.message;
statusDiv.className = "error";
console.error("错误:", error);
});
});
// 初始加载时检查默认URL图片
window.addEventListener('load', function() {
const preview = document.getElementById('urlPreview');
preview.onerror = function() {
preview.alt = "无法加载默认图片";
preview.src = "";
};
});
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 709 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+93 -5
View File
@@ -79,6 +79,31 @@
.error { .error {
color: red; color: red;
} }
.option-box {
margin: 15px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.option-box label {
display: block;
margin-bottom: 10px;
}
.cloth-len-select {
margin: 15px 0;
}
.cloth-len-select label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.cloth-len-select select {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
</style> </style>
</head> </head>
<body> <body>
@@ -96,11 +121,42 @@
<input type="file" id="clothInput" accept="image/*"> <input type="file" id="clothInput" accept="image/*">
<img id="clothPreview" class="image-preview" alt="衣服图片预览"> <img id="clothPreview" class="image-preview" alt="衣服图片预览">
</div> </div>
<div class="option-box"> </div>
<div class="image-upload-container">
<div class="image-upload-box">
<h3>裤子图片</h3>
<input type="file" id="kuziInput" accept="image/*">
<img id="kuziPreview" class="image-preview" alt="裤子图片预览">
</div>
<div class="cloth-len-select">
<label for="clothLenSelect">选择服装长度:</label>
<select id="clothLenSelect">
<option value="胸"></option>
<option value="腰"></option>
<option value="跨"></option>
<option value="大腿">大腿</option>
<option value="膝盖">膝盖</option>
<option value="小腿">小腿</option>
<option value="脚踝">脚踝</option>
<option value="拖地">拖地</option>
</select>
</div>
</div>
<div class="option-box">
<label> <label>
<input type="checkbox" id="no2Checkbox"> 设置 no2 不要两步(一步完成) <input type="checkbox" id="no2Checkbox"> 设置 no2 不要两步(一步完成)
</label> </label>
</div> <br>
<label>
<input type="checkbox" id="tuodiCheckbox"> 设置 tuodi(拖地)
</label>
<br>
<label>
<input type="checkbox" id="suitCheckbox"> 设置 suit(套装)
</label>
</div> </div>
<button id="submitBtn">提交处理</button> <button id="submitBtn">提交处理</button>
@@ -140,11 +196,29 @@
} }
}); });
document.getElementById('kuziInput').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
const img = document.getElementById('kuziPreview');
img.src = event.target.result;
img.style.display = 'block';
};
reader.readAsDataURL(file);
}
});
// 提交处理 // 提交处理
document.getElementById('submitBtn').addEventListener('click', function() { document.getElementById('submitBtn').addEventListener('click', function() {
const humanFile = document.getElementById('humanInput').files[0]; const humanFile = document.getElementById('humanInput').files[0];
const clothFile = document.getElementById('clothInput').files[0]; const clothFile = document.getElementById('clothInput').files[0];
const kuziFile = document.getElementById('kuziInput').files[0];
const no2 = document.getElementById("no2Checkbox").checked; const no2 = document.getElementById("no2Checkbox").checked;
const tuodi = document.getElementById("tuodiCheckbox").checked;
const suit = document.getElementById("suitCheckbox").checked;
const clothLen = document.getElementById("clothLenSelect").value;
if (!humanFile || !clothFile) { if (!humanFile || !clothFile) {
alert('请同时选择人体图片和衣服图片!'); alert('请同时选择人体图片和衣服图片!');
@@ -158,20 +232,32 @@
// 读取图片并转换为Base64(包含完整前缀) // 读取图片并转换为Base64(包含完整前缀)
Promise.all([ Promise.all([
readFileAsDataURL(humanFile), readFileAsDataURL(humanFile),
readFileAsDataURL(clothFile) readFileAsDataURL(clothFile),
]).then(([humanDataURL, clothDataURL]) => { kuziFile ? readFileAsDataURL(kuziFile) : Promise.resolve(null)
]).then(([humanDataURL, clothDataURL, kuziDataURL]) => {
// 准备请求数据 // 准备请求数据
const data = { const data = {
human_img: humanDataURL, // 包含完整前缀的Base64 human_img: humanDataURL, // 包含完整前缀的Base64
cloth_img: clothDataURL, // 包含完整前缀的Base64 cloth_img: clothDataURL, // 包含完整前缀的Base64
output_format: "url", output_format: "url",
no2: no2, no2: no2,
tuodi: tuodi,
suit: suit,
cloth_len: clothLen // 新增的服装长度字段
}; };
if(kuziDataURL)
{
data.kuzi_img = kuziDataURL;
}
console.log("准备发送的数据:", data); // 调试用 console.log("准备发送的数据:", data); // 调试用
// 调用API // 调用API
fetch('http://112.126.94.241:18888/change_cloth_base64', { fetch('http://117.50.44.174:28888/change_cloth_base64', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -198,6 +284,8 @@
<p><img src="${data.url}" style="max-width: 100%; margin-top: 10px;"></p> <p><img src="${data.url}" style="max-width: 100%; margin-top: 10px;"></p>
<a href="${data.first_url}" target="_blank">${data.url}</a> <a href="${data.first_url}" target="_blank">${data.url}</a>
<p><img src="${data.first_url}" style="max-width: 100%; margin-top: 10px;"></p> <p><img src="${data.first_url}" style="max-width: 100%; margin-top: 10px;"></p>
<a href="${data.second_url}" target="_blank">${data.url}</a>
<p><img src="${data.second_url}" style="max-width: 100%; margin-top: 10px;"></p>
`; `;
} else { } else {
resultDiv.innerHTML = ` resultDiv.innerHTML = `
+3 -3
View File
@@ -94,12 +94,12 @@
<div class="input-group"> <div class="input-group">
<label for="human-url">人体图片URL:</label> <label for="human-url">人体图片URL:</label>
<input type="text" id="human-url" value="http://112.126.94.241:18888/static/imgs/human_20250713_091718_fb1f8a05.jpg"> <input type="text" id="human-url" value="http://117.50.44.174:18888/static/imgs/human_20250713_091718_fb1f8a05.jpg">
</div> </div>
<div class="input-group"> <div class="input-group">
<label for="cloth-url">衣服图片URL:</label> <label for="cloth-url">衣服图片URL:</label>
<input type="text" id="cloth-url" value="http://112.126.94.241:18888/static/imgs/cloth_20250713_092536_279335d2.jpg"> <input type="text" id="cloth-url" value="http://117.50.44.174:18888/static/imgs/cloth_20250713_092536_279335d2.jpg">
</div> </div>
<button id="submit-btn">提交处理</button> <button id="submit-btn">提交处理</button>
@@ -136,7 +136,7 @@
try { try {
// 发送POST请求 // 发送POST请求
const response = await fetch('http://112.126.94.241:18888/change_cloth', { const response = await fetch('http://117.50.44.174:18888/change_cloth', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
+1 -1
View File
@@ -246,7 +246,7 @@
// 获取服务器状态数据 // 获取服务器状态数据
async function fetchServerStatus() { async function fetchServerStatus() {
try { try {
const response = await fetch('http://112.126.94.241:18018/get_server_state'); const response = await fetch('http://117.50.44.174:18018/get_server_state');
if (!response.ok) throw new Error('网络响应不正常'); if (!response.ok) throw new Error('网络响应不正常');
return await response.json(); return await response.json();
} catch (error) { } catch (error) {
+1 -1
View File
@@ -4,7 +4,7 @@ import json
# 1. 提交任务 # 1. 提交任务
with open('/home/szlc/code/ComfyUI/change_cloth/basic_api.json', 'r', encoding='utf-8') as file: with open('/home/xsl/code/ComfyUI/change_cloth/basic_api.json', 'r', encoding='utf-8') as file:
prompt_text = file.read() prompt_text = file.read()
prompt = json.loads(prompt_text) prompt = json.loads(prompt_text)
+3 -3
View File
@@ -27,13 +27,13 @@ def image_to_base64(file_path, mime_type=None):
return f"data:{mime_type};base64,{encoded_string}" return f"data:{mime_type};base64,{encoded_string}"
if __name__ == '__main__': if __name__ == '__main__':
url = 'http://112.126.94.241:18018/change_cloth_base64' url = 'http://117.50.44.174:18018/change_cloth_base64'
headers = {'Content-Type': 'application/json'} headers = {'Content-Type': 'application/json'}
img64_human_str = image_to_base64("/home/szlc/code/ComfyUI/input/girl_full.jpg") img64_human_str = image_to_base64("/home/xsl/code/ComfyUI/input/girl_full.jpg")
data = {} data = {}
data['human_img'] = img64_human_str data['human_img'] = img64_human_str
img64_cloth_str = image_to_base64("/home/szlc/code/ComfyUI/input/cloth_short.jpg") img64_cloth_str = image_to_base64("/home/xsl/code/ComfyUI/input/cloth_short.jpg")
data['cloth_img'] = img64_cloth_str data['cloth_img'] = img64_cloth_str
data['output_format'] = "url" data['output_format'] = "url"
+6 -3
View File
@@ -183,6 +183,8 @@ def call_remote_gpu_server(task_data_str, server=None):
"human_url": task_data['request']['human_url'], "human_url": task_data['request']['human_url'],
"cloth_url": task_data['request']["cloth_url"], "cloth_url": task_data['request']["cloth_url"],
"no2":task_data['request']['no2'], "no2":task_data['request']['no2'],
"tuodi":task_data['request']['tuodi'],
"kuzi":task_data['request']['kuzi'],
"output_format":task_data['request']['output_format'] "output_format":task_data['request']['output_format']
} }
@@ -307,7 +309,7 @@ def main_worker():
serverindex = 0 serverindex = 0
def regServer(instance, ip): def regServer(instance, ip):
global serverindex global serverindex
registerGpuServer(f"s{serverindex}_1_{instance}", f"http://{ip}:8888", True) registerGpuServer(f"s{serverindex}_1_{instance}", f"http://{ip}", True)
serverindex += 1 serverindex += 1
@@ -316,7 +318,8 @@ if __name__ == '__main__':
print(f"[Worker] Starting with PID: {os.getpid()}") print(f"[Worker] Starting with PID: {os.getpid()}")
redis_conn.set(GPU_SERVER_LIST, "[]") redis_conn.set(GPU_SERVER_LIST, "[]")
regServer("一号", "192.168.101.118") regServer("5090", "112.126.94.241:28888")
regServer("二号", "192.168.101.221") # regServer("一号", "192.168.101.118:8888")
# regServer("二号", "192.168.101.221:8888")
main_worker() main_worker()
+345
View File
@@ -0,0 +1,345 @@
{
"6": {
"inputs": {
"text": "asian girl,knee-length shot ,model pose,hands are at the sides of the body,smile,wearing black tube top and micro skirt,simple ,white background,32k,high detail,and face is illuminated by soft side light and natural light. The sunlight spills over the white wall behind.",
"clip": [
"68",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"10": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"16": {
"inputs": {
"sampler_name": "dpmpp_2m"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"17": {
"inputs": {
"scheduler": "sgm_uniform",
"steps": 30,
"denoise": 1,
"model": [
"63",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "BasicScheduler"
}
},
"25": {
"inputs": {
"noise_seed": 817211431292667
},
"class_type": "RandomNoise",
"_meta": {
"title": "RandomNoise"
}
},
"26": {
"inputs": {
"guidance": 10,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"27": {
"inputs": {
"width": 768,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"45": {
"inputs": {
"pulid_file": "pulid_flux_v0.9.1.safetensors"
},
"class_type": "PulidFluxModelLoader",
"_meta": {
"title": "Load PuLID Flux Model"
}
},
"47": {
"inputs": {
"model": [
"62",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "BasicGuider"
}
},
"48": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"47",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"49": {
"inputs": {
"samples": [
"48",
0
],
"vae": [
"10",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"51": {
"inputs": {},
"class_type": "PulidFluxEvaClipLoader",
"_meta": {
"title": "Load Eva Clip (PuLID Flux)"
}
},
"53": {
"inputs": {
"provider": "CUDA"
},
"class_type": "PulidFluxInsightFaceLoader",
"_meta": {
"title": "Load InsightFace (PuLID Flux)"
}
},
"62": {
"inputs": {
"weight": 1.0000000000000002,
"start_at": 0,
"end_at": 1,
"model": [
"68",
0
],
"pulid_flux": [
"45",
0
],
"eva_clip": [
"51",
0
],
"face_analysis": [
"53",
0
],
"image": [
"93",
0
]
},
"class_type": "ApplyPulidFlux",
"_meta": {
"title": "Apply PuLID Flux"
}
},
"63": {
"inputs": {
"unet_name": "flux1-dev-fp8.safetensors",
"weight_dtype": "fp8_e4m3fn"
},
"class_type": "UNETLoader",
"_meta": {
"title": "Load Diffusion Model"
}
},
"64": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "ViT-L-14-TEXT-detail-improved-hiT-GmP-HF.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"65": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"49",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"68": {
"inputs": {
"PowerLoraLoaderHeaderWidget": {
"type": "PowerLoraLoaderHeaderWidget"
},
" Add Lora": "",
"model": [
"63",
0
],
"clip": [
"64",
0
]
},
"class_type": "Power Lora Loader (rgthree)",
"_meta": {
"title": "Power Lora Loader (rgthree)"
}
},
"86": {
"inputs": {
"anything": [
"17",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"87": {
"inputs": {
"anything": [
"68",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"88": {
"inputs": {
"anything": [
"62",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"89": {
"inputs": {
"anything": [
"47",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"90": {
"inputs": {
"anything": [
"48",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"91": {
"inputs": {
"anything": [
"49",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"92": {
"inputs": {
"anything": [
"49",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"93": {
"inputs": {
"image": "qwerqwe.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
}
}
File diff suppressed because one or more lines are too long
+354
View File
@@ -0,0 +1,354 @@
{
"6": {
"inputs": {
"text": "asian man,tall,knee-length shot,model pose,hands are at the sides of the body,smile,wearing black short pants,simple white background,The sunlight spills over the white wall behind,32k,",
"clip": [
"68",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"10": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "Load VAE"
}
},
"16": {
"inputs": {
"sampler_name": "dpmpp_2m"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"17": {
"inputs": {
"scheduler": "sgm_uniform",
"steps": 30,
"denoise": 1,
"model": [
"63",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "BasicScheduler"
}
},
"25": {
"inputs": {
"noise_seed": 307959081040868
},
"class_type": "RandomNoise",
"_meta": {
"title": "RandomNoise"
}
},
"26": {
"inputs": {
"guidance": 10,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"27": {
"inputs": {
"width": 768,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"45": {
"inputs": {
"pulid_file": "pulid_flux_v0.9.1.safetensors"
},
"class_type": "PulidFluxModelLoader",
"_meta": {
"title": "Load PuLID Flux Model"
}
},
"47": {
"inputs": {
"model": [
"62",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "BasicGuider"
}
},
"48": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"47",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"49": {
"inputs": {
"samples": [
"48",
0
],
"vae": [
"10",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"51": {
"inputs": {},
"class_type": "PulidFluxEvaClipLoader",
"_meta": {
"title": "Load Eva Clip (PuLID Flux)"
}
},
"53": {
"inputs": {
"provider": "CUDA"
},
"class_type": "PulidFluxInsightFaceLoader",
"_meta": {
"title": "Load InsightFace (PuLID Flux)"
}
},
"62": {
"inputs": {
"weight": 1.0000000000000002,
"start_at": 0,
"end_at": 1,
"model": [
"68",
0
],
"pulid_flux": [
"45",
0
],
"eva_clip": [
"51",
0
],
"face_analysis": [
"53",
0
],
"image": [
"93",
0
]
},
"class_type": "ApplyPulidFlux",
"_meta": {
"title": "Apply PuLID Flux"
}
},
"63": {
"inputs": {
"unet_name": "flux1-dev-fp8.safetensors",
"weight_dtype": "fp8_e4m3fn"
},
"class_type": "UNETLoader",
"_meta": {
"title": "Load Diffusion Model"
}
},
"64": {
"inputs": {
"clip_name1": "flux/t5xxl_fp16.safetensors",
"clip_name2": "ViT-L-14-TEXT-detail-improved-hiT-GmP-HF.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "DualCLIPLoader"
}
},
"65": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"49",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"68": {
"inputs": {
"PowerLoraLoaderHeaderWidget": {
"type": "PowerLoraLoaderHeaderWidget"
},
" Add Lora": "",
"model": [
"63",
0
],
"clip": [
"64",
0
]
},
"class_type": "Power Lora Loader (rgthree)",
"_meta": {
"title": "Power Lora Loader (rgthree)"
}
},
"86": {
"inputs": {
"anything": [
"17",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"87": {
"inputs": {
"anything": [
"68",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"88": {
"inputs": {
"anything": [
"62",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"89": {
"inputs": {
"anything": [
"47",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"90": {
"inputs": {
"anything": [
"48",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"91": {
"inputs": {
"anything": [
"49",
0
]
},
"class_type": "easy cleanGpuUsed",
"_meta": {
"title": "Clean VRAM Used"
}
},
"92": {
"inputs": {
"anything": [
"49",
0
]
},
"class_type": "easy clearCacheAll",
"_meta": {
"title": "Clear Cache All"
}
},
"93": {
"inputs": {
"image": "微信图片_20250813204256_128.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"94": {
"inputs": {
"text": "sian girl,knee-length shot ,model pose,hands are at the sides of the body,smile,wearing black tube top and micro skirt,simple ,white background,32k,high detail,and face is illuminated by soft side light and natural light. The sunlight spills over the white wall behind."
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
}
}