添加单张图片变换

This commit is contained in:
Your Name
2026-05-06 00:12:55 +08:00
parent 0b9b5d21ff
commit 47ff49dc19
7 changed files with 1119 additions and 39 deletions
+44 -26
View File
@@ -7,61 +7,79 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
Each service runs independently and must be started separately:
```bash
# Shirt-only try-on service (port 8888)
# Single-image edit service (port 12221)
python change1/service1.py
# Shirt-only try-on service (port 12222)
python change2/service2.py
# Shirt + pants try-on service (port 8889)
# Shirt + pants try-on service (port 12223)
python change3/service3.py
# Gateway router (port 28888) — requires Flask
python change_app.py
```
ComfyUI must be running at `http://127.0.0.1:8188` before starting the services.
ComfyUI must be reachable at the URL configured in each service (currently `http://112.126.94.241:28188`, with `:38188` as backup).
## Dependencies
```bash
pip install fastapi uvicorn httpx pydantic flask requests
pip install fastapi uvicorn httpx pydantic flask requests oss2 pillow
```
## Architecture
This is a three-tier AI virtual try-on system built around ComfyUI.
This is an AI virtual try-on / image-edit system built around ComfyUI, fronted by three FastAPI workers and a Flask gateway.
```
Client
└─► change_app.py (Flask, port 28888) ← Gateway router
├─► change2/service2.py (FastAPI, port 8888) ← shirt-only
─► change3/service3.py (FastAPI, port 8889) ← shirt + pants
└─► ComfyUI (port 8188)
└─► change_app.py (Flask, port 28888) ← Gateway router
├─► change1/service1.py (FastAPI, 12221) ← single image (model only)
─► change2/service2.py (FastAPI, 12222) ← model + shirt
└─► change3/service3.py (FastAPI, 12223) ← model + shirt + pants
└─► ComfyUI
```
**Gateway** (`change_app.py`): Accepts `POST /change_cloth_base64` with `human_img`, `cloth_img`, and optional `kuzi_img` (pants). Routes to `service3` when `kuzi_img` is present, otherwise to `service2`. Both backends are called at `/do_change_cloth`.
**Gateway** (`change_app.py`): Accepts `POST /change_cloth_base64` with `human_img` (required) and optional `cloth_img` / `kuzi_img` / `change_desc`. Routing rules:
- `kuzi_img` present → `service3` (12223)
- `cloth_img` present (no `kuzi_img`) → `service2` (12222)
- only `human_img``service1` (12221)
**service2** (`change2/service2.py`): Handles shirt-only try-on. Exposes `POST /try-on` with `model_image` + `shirt_image`. Uses ComfyUI workflow `change2_1_ex.json`.
All backends expose `POST /try-on` and return `{ "result_url": "<oss url>" }`. The gateway wraps that into `{ "ret": 0, "state": 0, "msg": "success", "data": <oss url> }`.
**service3** (`change3/service3.py`): Handles shirt + pants try-on. Exposes `POST /try-on` with `model_image` + `shirt_image` + `pants_image`. Uses ComfyUI workflow `change2_2_0308.json`.
**service1** (`change1/service1.py`): Single-image edit (e.g. background replacement, full-body generation from a reference). Exposes `POST /try-on` with `model_image` + optional `change_desc`. Uses ComfyUI workflow `change1.json`.
**service2** (`change2/service2.py`): Shirt-only try-on. Exposes `POST /try-on` with `model_image` + `shirt_image` + optional `change_desc`. Uses ComfyUI workflow `change2_1_ex.json`.
**service3** (`change3/service3.py`): Shirt + pants try-on. Exposes `POST /try-on` with `model_image` + `shirt_image` + `pants_image` + optional `change_desc`. Uses ComfyUI workflow `change2_2_0308.json`.
### ComfyUI Workflow Integration
Both services dynamically modify a JSON workflow template before submission:
Each service dynamically modifies a JSON workflow template before submission:
| Node ID | Purpose | service2 | service3 |
|---------|---------|----------|----------|
| `"11"` | Model/person image | ✓ | ✓ |
| `"10"` | Shirt image | ✓ | ✓ |
| `"4"` | Pants image | — | ✓ |
| `"33"` | Output image | ✓ | ✓ |
| Node ID | Purpose | service1 | service2 | service3 |
|---------|---------|----------|----------|----------|
| `"11"` | Model/person image (LoadImage) | ✓ | ✓ | ✓ |
| `"10"` | Shirt image (LoadImage) | — | ✓ | ✓ |
| `"4"` | Pants image (LoadImage) | — | — | ✓ |
| `"31"` | Text prompt (PrimitiveStringMultiline, overridden when `change_desc` is non-empty) | ✓ | ✓ | ✓ |
| `"33"` | Output image (SaveImage) | ✓ | ✓ | ✓ |
The request flow within each service:
1. Decode base64 images
2. Upload images to ComfyUI (`/upload/image`) with UUID-prefixed filenames to avoid cache collisions
3. Inject filenames into workflow node inputs
4. Submit workflow to ComfyUI queue (`/prompt`)
5. Poll `/history/{prompt_id}` until `status.completed` is true (max 300s timeout, 2s poll interval)
6. Download result from `/view` and return as base64
1. Pick a healthy ComfyUI host (primary, fallback to backup)
2. Decode base64 images
3. Upload images to ComfyUI (`/upload/image`) with UUID-prefixed filenames to avoid cache collisions
4. Inject filenames into workflow node inputs; if `change_desc` is non-empty, replace node `31` inputs with `{"value": change_desc}`
5. Submit workflow to ComfyUI queue (`/prompt`)
6. Poll `/history/{prompt_id}` until `status.completed` is true (max 300s timeout, 2s poll interval)
7. Download the result from `/view`, push it to Aliyun OSS, and return the signed URL
### Frontend
Each service has its own test UI at `/` (served from `<service_dir>/static/index.html`). The `change2` UI accepts 2 images; `change3` accepts 3 images. Both POST directly to the service's `/try-on` endpoint.
Each service has its own test UI at `/` (served from `<service_dir>/static/index.html`):
- `change1` UI: 1 upload card (model) + prompt panel
- `change2` UI: 2 upload cards (model, shirt) + prompt panel
- `change3` UI: 3 upload cards (model, shirt, pants) + prompt panel
All three POST directly to the service's own `/try-on` endpoint.