news 2026/6/6 19:56:39

img2img

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
img2img

智慧衣橱虚拟试穿实践:从占位 UI到 Sophnet 双图图生图的落地思考

一、写在前面:

做智慧衣橱时,产品页面上最早写的是AI 试穿 / 图生图 · 接入中。很长一段时间里,我把试穿和小衣对话助手混在一起想——以为在聊天框里发一张衣服图,大模型说几句搭配建议,就算AI 试衣了。

后来明白:虚拟试穿本质上是图像问题,不是文本问题。

- 对话大模型:输入文字 → 输出文字(或附带描述)
- 虚拟试穿:输入 人物图 + 服装图 → 输出 一张新的合成图

这在技术分类上属于 图生图(Image-to-Image) 或 条件图像编辑:以人物照为底,用服装图和 Prompt 作为条件,让扩散模型生成穿上这件衣服的效果图。

专用 VTON(Virtual Try-On)扩散模型(如 IDM-VTON)效果最好,但需要 GPU 或海外 API。我们团队当时 只有 Sophnet 平台的 API Key,没有阿里云 DashScope 原厂 Key,也没有 Replicate 账号。

于是做了一个务实选择:用 Sophnet 上的 `Qwen-Image-Edit-2509` 做双图 + Prompt的近似试穿——不是严格意义上的 VTON,但在工程上能跑通、能演示、能写进论文,而且和现有 Key 兼容。

二、近似试穿

2.1 三种路线,我们选了中间那条

路线做法难度效果

A. 专用 VTON

IDM-VTON 等双图模型

高(GPU/海外 API)

最好

B. 图像编辑 / 图生图

双图 +「穿上这件衣服」Prompt

够用,不稳定

C. 纯文生图

只描述衣服,不喂服装图

衣服对不上

我们走的是 B:在 Sophnet 文档里,`Qwen-Image-Edit-2509` 支持 1~3 张参考图 + 编辑指令,任务类型标注为 I2I(图生图),这和让人物穿上某件衣服的需求是对齐的。

2.2 和专用 VTON差在哪里(心里要有数)

图生图近似试穿 不保证:

- 服装纹理 1:1 还原(Logo、条纹可能糊)
- 人脸 100% 不变(偶发换脸感)
- 复杂姿态下的遮挡关系

但它 能保证:

- 端到端链路:App 选图 → 后端 → 云 API → 结果 URL → 展示
- 和衣橱数据打通:服装图可直接来自已录入单品
-基于图生图条件编辑的近似虚拟试穿,后续可升级为专用 VTON

三、整体架构:Key 绝不进 App

个人理解里,移动端 AI 接入的第一原则是:API Key 只放服务端。

```
Android VirtualTryOnScreen
│ Multipart: person_image + garment_image
│ Header: Authorization: Bearer <登录 JWT>

FastAPI /api/v1/ai/tryon
│ 鉴权 → 存图 → tryon_service.run_tryon()

Sophnet Qwen-Image-Edit-2509
│ 异步任务:创建 → 轮询 → 取 results[0].url

backend/uploads/tryon/ → App 用 Coil 加载 result_url
```

令试穿单独一个页面:

1. 图生图慢(常 30~120 秒),不适合在聊天气泡里干等
2. 两张图 + 轮询,交互更像工具而不是对话
3. 以后换 VTON 模型,只改 `tryon_service.py`,App 协议不变

四、后端实现

4.1 接口设计:简单、可演示、可扩展

FastAPI 路由(节选):

```python
@app.post("/api/v1/ai/tryon", response_model=TryOnResponse)
async def ai_tryon(
user_id: Annotated[int, Depends(current_user_id)],
person_image: UploadFile = File(...),
garment_image: UploadFile = File(...),
) -> TryOnResponse:
# 校验 image/ → 落临时文件 → run_tryon()
...
return TryOnResponse(payload)
```

响应里我刻意加了 `mode` 字段:

- `provider`:Sophnet 图生图成功
- `demo`:未配置 Key,或调用失败时回显人物图

这是个人很看重的一点:没有 Key 的日子也要能答辩演示 UI。Demo 不是造假,而是工程上的 降级策略(Graceful Degradation)。

4.2 核心:双图顺序 + Prompt 设计

Sophnet 文档写得很清楚:`input.images` 支持 1~3 张图,多图时按数组顺序,且 输出宽高比以最后一张为准。

因此我们的顺序是:

```python
"images": [garment_data_uri, person_data_uri]
# 图1 = 服装,图2 = 人物 → 输出比例跟人物走
```

Prompt 是反复试出来的(可放 `.env` 覆盖):

```python
DEFAULT_TRYON_PROMPT = (
"参考图1中的服装单品,让图2中的人物自然穿上该服装。"
"保持图2的人脸、发型、体态、背景不变,服装贴合身体,写实摄影风格,高清。"
)

DEFAULT_NEGATIVE_PROMPT = (
"模糊,低质量,变形的脸,多余的手指,文字水印,卡通,插画风格,"
"服装错位,头部替换,背景突变"
)
```

思考: Prompt 写图1 / 图2是和数组顺序绑定的;若以后改成人物在前、服装在后,Prompt 必须一起改,否则模型会懵。

4.3 异步任务:创建 + 轮询

Sophnet 图片接口是 异步 的:POST 返回 `taskId`,再 GET 查状态直到 `SUCCEEDED`。

创建任务(节选):

```python
payload = {
"model": "Qwen-Image-Edit-2509",
"input": {
"prompt": prompt,
"negative_prompt": negative,
"images": [garment_data_uri, person_data_uri],
},
"parameters": {
"size": "12801280",
"watermark": False,
"prompt_extend": True,
"save_to_jpeg": True,
},
}
r = client.post(SOPHNET_IMAGE_TASK_URL, headers={...}, json=payload)
task_id = output["taskId"]
```

轮询逻辑(个人实现要点):

```python
while time.time() < deadline:
r = client.get(f".../task/{task_id}", headers={...})
status = output.get("taskStatus", "").upper()
if status == "SUCCEEDED":
return output["results"][0]["url"]
if status in ("FAILED", "CANCELED"):
raise RuntimeError(...)
time.sleep(2) # 默认 2 秒一轮,最多 180 秒
```

响应体有时包在 `output` 里,有时在 `result` 里,我写了 `_unwrap_output()` 做兼容,避免联调时明明成功却解析失败。

图生图失败时不向 App 抛 500,而是 `print` 日志 + 降级 demo。用户至少能看到人物回显和错误提示,而不是整页崩溃。

4.4 环境变量(`.env`)

```env
TRYON_PROVIDER=sophnet
SOPHNET_API_KEY=你的Key
TRYON_MODEL=Qwen-Image-Edit-2509
TRYON_API_BASE_URL=https://www.sophnet.com/api/open-apis/projects/easyllms/imagegenerator/task
TRYON_POLL_MAX_SEC=180
```

Sophnet 文档:[视觉模型](https://www.sophnet.com/docs/component/vision_model.html)

五、Android 端实现与思考

5.1 页面:VirtualTryOnScreen

交互我设计成三步,尽量像工具不像聊天:

1. 选人物照(相册)
2. 选服装图(相册 或 衣橱横滑选单品)
3. 点生成试穿效果→ 展示 `result_url`

实现的衣橱联动:服装图不必重新拍,直接用 DataStore 里已有 `imageUri`,形成我的衣橱 → 试穿预览闭环。

5.2 上传:Retrofit Multipart

```kotlin
@Multipart
@POST("api/v1/ai/tryon")
suspend fun tryOn(
@Part personImage: MultipartBody.Part,
@Part garmentImage: MultipartBody.Part,
): TryOnResponseDto
```

`AiRepository` 里从 `content://` 读字节,和上传头像同一套路:

```kotlin
suspend fun virtualTryOn(personUri: Uri, garmentUri: Uri): TryOnResponseDto {
val personPart = uriToPart(personUri, "person_image", "person.jpg")
val garmentPart = uriToPart(garmentUri, "garment_image", "garment.jpg")
return api.tryOn(personPart, garmentPart)
}
```

5.3 超时:图生图 ≠ 登录接口

普通接口 readTimeout 20s;图生图单独 `aiApi()` 拉到 120s。这是实际联调时得到的经验——异步轮询在后端做,但整次 HTTP 仍可能接近一分钟。

5.4 登录与游客

试穿接口复用 JWT。游客点击生成会引导登录——既是安全(防刷 API),也是产品逻辑(试穿算深度功能)。

六、联调步骤

1. `cd backend && pip install httpx && uvicorn main:app --host 0.0.0.0 --port 8080`
2. `.env` 填 `SOPHNET_API_KEY`
3. Android `local.properties`:`WARDROBE_API_BASE_URL=http://10.0.2.2:8080/`(模拟器)
4. App 登录 → 搭配 → AI 实验室 → AI 试穿 / 虚拟上身
5. 人物照 + 服装图 → 生成
6. 成功:`mode=provider`;未配 Key:`mode=demo` 回显人物图

七、效果与局限:

效果:

- 认清试穿 = 图生图,没有硬塞进 LLM 聊天
- 服务端代理 Key,JWT 鉴权
- 演示降级 + 真实模式用 `mode` 区分
- Sophnet 双图 I2I 与现有 Key 兼容,零 GPU

局限:

- 效果随 Prompt、照片质量波动大
- 专用 VTON 在衣服还原度上仍明显更好
- 大图 Base64 上传,尚未做压缩/去背景预处理
- 轮询在后端同步阻塞,高并发时要改 task 队列

若继续迭代,我会按这个顺序:

1. 上传前缩放到短边 768、服装图去背景
2. 后端改异步:POST 返回 task_id,App 轮询
3. 有余力再换 Replicate IDM-VTON 或万相试衣专用接口

八、总结

本项目的虚拟试穿模块,是在智慧衣橱场景下对图生图(Image-to-Image)技术的一次工程实践:客户端采集人物照与服装单品图,经 FastAPI 服务端调用 Sophnet 平台的 Qwen-Image-Edit-2509 图像编辑模型,通过双图输入与自然语言编辑指令生成近似上身效果。该方案属于 条件图像编辑式近似试穿,与专用 VTON 扩散模型相比实现成本更低,便于在课程项目中完成端到端验证;API 密钥部署于服务端,移动端仅传输业务图片与 JWT,兼顾安全与可扩展性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 19:55:33

企业法务部搭建诉讼管理看板的完整指南:从数据收集到可视化监控

&#x1f4cc; 摘要 企业法务部门每天面对大量诉讼案件&#xff0c;但案件信息分散在 Excel、邮件和微信群中&#xff0c;总部看不清全貌&#xff0c;子公司的案件上报总是迟缓缺漏。本文从企业法务的实际场景出发&#xff0c;详细讲解如何搭建一套诉讼案件管理看板——从数据采…

作者头像 李华
网站建设 2026/6/6 19:54:20

如何在3分钟内免费获得苹果专业字体?PingFangSC跨平台终极指南

如何在3分钟内免费获得苹果专业字体&#xff1f;PingFangSC跨平台终极指南 【免费下载链接】PingFangSC PingFangSC字体包文件、苹果平方字体文件&#xff0c;包含ttf和woff2格式 项目地址: https://gitcode.com/gh_mirrors/pi/PingFangSC 你是否曾羡慕Mac电脑上那些清晰…

作者头像 李华
网站建设 2026/6/6 19:53:17

WrenAI容器化实践:构建企业级AI数据上下文层

WrenAI容器化实践&#xff1a;构建企业级AI数据上下文层 【免费下载链接】WrenAI Give AI agents the context to query business data correctly through the open context layer that gives AI agents grounded, governed memory, context, SQL across 20 data sources, that…

作者头像 李华
网站建设 2026/6/6 19:47:29

《扣子如何让OpenClaw技能开发提速》

创意的产生只需要一瞬间&#xff0c;而将创意转化为可运行的产品却需要耗费数十倍甚至上百倍的时间。这种时间差导致大量优秀的想法在等待实现的过程中逐渐失去价值&#xff0c;也让许多开发者陷入了无休止的重复劳动中。扣子可视化工具的出现&#xff0c;正是为了打破这种时间…

作者头像 李华