添加单张图片变换
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user