diff --git a/change2/CLAUDE.md b/change2/CLAUDE.md new file mode 100644 index 0000000..f0a4807 --- /dev/null +++ b/change2/CLAUDE.md @@ -0,0 +1,71 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a FastAPI-based virtual try-on service that integrates with ComfyUI for AI-powered clothing try-on. The service accepts base64-encoded images (model photo, shirt, pants) and returns a generated try-on result. + +## Running the Service + +Start the server: +```bash +python service2.py +``` + +The server runs on `http://0.0.0.0:47698` by default. + +## Dependencies + +Required Python packages (install via pip): +- fastapi +- uvicorn +- httpx +- pydantic + +## Architecture + +### Request Flow +1. Client sends POST to `/try-on` with base64 images (model_image, shirt_image, pants_image) +2. Server decodes images and uploads to ComfyUI at `http://127.0.0.1:8188` +3. Server modifies workflow JSON (change2_1_ex.json) with uploaded image filenames +4. Workflow submitted to ComfyUI queue +5. Server polls ComfyUI history endpoint until completion (max 300s timeout) +6. Result image downloaded from ComfyUI and returned as base64 + +### Key Components + +**service2.py**: Main FastAPI application +- `/try-on`: Main endpoint for virtual try-on +- `/health`: Health check endpoint +- `/`: Serves static frontend (index.html) + +**change2_1_ex.json**: ComfyUI workflow configuration +- Node "11": Model image input (LoadImage) +- Node "10": Shirt image input (LoadImage) +- Node "33": Output image (SaveImage) +- Node "31": Text prompt for image editing + +**static/index.html**: Frontend interface for testing + +### ComfyUI Integration + +The service expects ComfyUI to be running at `http://127.0.0.1:8188` with: +- FireRed-Image-Edit model loaded +- Qwen 2.5 VL CLIP model +- Required custom nodes for QwenEditConfigPreparer, QwenEditOutputExtractor + +### Workflow Modification + +When processing requests, the code dynamically updates these workflow nodes: +- `workflow["11"]["inputs"]["image"]`: Model photo filename +- `workflow["10"]["inputs"]["image"]`: Shirt photo filename +- `workflow["31"]["inputs"]["value"]`: Text prompt (currently hardcoded in Chinese) + +## Important Notes + +- Images are uploaded with unique filenames (UUID prefix) to avoid caching issues +- The pants_image parameter is currently unused (commented out in code) +- Workflow uses 8 sampling steps with euler sampler and beta scheduler +- Output resolution is 768x1024 pixels +- CORS is enabled for all origins diff --git a/change2/service2.py b/change2/service2.py index 5f14c4b..31aba2c 100644 --- a/change2/service2.py +++ b/change2/service2.py @@ -44,7 +44,6 @@ app.add_middleware( class TryOnRequest(BaseModel): model_image: str # base64 模特图片 shirt_image: str # base64 上衣图片 - pants_image: str # base64 裤子图片 class TryOnResponse(BaseModel): @@ -113,7 +112,6 @@ async def try_on(req: TryOnRequest): 换装接口 - model_image: 模特图片 base64 - shirt_image: 上衣图片 base64 - - pants_image: 裤子图片 base64 返回 result_image: 换装结果 base64 """ @@ -124,11 +122,10 @@ async def try_on(req: TryOnRequest): async with httpx.AsyncClient(timeout=60.0) as client: - # 解码三张图片 + # 解码两张图片 try: model_bytes = decode_base64_image(req.model_image) shirt_bytes = decode_base64_image(req.shirt_image) - # pants_bytes = decode_base64_image(req.pants_image) except Exception as e: raise HTTPException(status_code=400, detail=f"图片解码失败: {e}") @@ -136,14 +133,12 @@ async def try_on(req: TryOnRequest): uid = uuid.uuid4().hex[:8] model_fname = f"model_{uid}.jpg" shirt_fname = f"shirt_{uid}.jpg" - # pants_fname = f"pants_{uid}.jpg" - # 并发上传三张图片 + # 并发上传两张图片 try: - model_name, shirt_name, pants_name = await asyncio.gather( + model_name, shirt_name = await asyncio.gather( upload_image(client, model_bytes, model_fname), upload_image(client, shirt_bytes, shirt_fname), - # upload_image(client, pants_bytes, pants_fname), ) except httpx.HTTPError as e: raise HTTPException(status_code=502, detail=f"上传图片到 ComfyUI 失败: {e}") @@ -151,7 +146,6 @@ async def try_on(req: TryOnRequest): # 修改工作流节点的图片输入 workflow[NODE_MODEL]["inputs"]["image"] = model_name workflow[NODE_SHIRT]["inputs"]["image"] = shirt_name - # workflow[NODE_PANTS]["inputs"]["image"] = pants_name # 提交工作流 try: diff --git a/change2/static/index.html b/change2/static/index.html index 8a3ca57..d2aeb53 100644 --- a/change2/static/index.html +++ b/change2/static/index.html @@ -37,7 +37,7 @@ .upload-grid { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(2, 1fr); gap: 20px; width: 100%; max-width: 900px; @@ -204,7 +204,7 @@
上传模特、上衣、裤子三张图片,AI 自动完成换装
+上传模特和上衣两张图片,AI 自动完成换装