# Image Cutout Avatar

> 把一张带背景的照片/游戏截图里的人物抠成透明 PNG（证件照/头像/贴纸用）。适用于「把这个人抠出来放进去」「只放上半身」「换成我的形象」等需求。含 rembg 安装、多主体自动择一、以及模型看不到图时的 ASCII 轮廓自检法。

- Skill: `paloma333/image-cutout-avatar` (Agent Skill)
- Install (CLI): `npx skillmds@latest add paloma333/image-cutout-avatar`
- Raw SKILL.md: https://api.skillmd.com/api/skills/paloma333/image-cutout-avatar/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Paloma333 (https://skillmd.com/u/paloma333)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/paloma333/image-cutout-avatar

---


# 人物抠图 → 透明 PNG

## 何时用

用户给一张图（自拍、游戏截图、插画）说「抠出来」「去掉背景」「只放上半身」「换掉原来的头像」。
先**不要**手工画蒙版，也不要用 ImageGen 重绘（会改变人物样貌）；走 rembg 分割 + 规则裁剪。

## 环境准备（只做一次）

```bash
python3 -m venv ~/.venvs/cutout
PY=~/.venvs/cutout/bin/python3          # 任意隔离 venv；不要装进系统 Python
$PY -m pip install rembg onnxruntime    # 首次运行会自动下载 u2net.onnx（176MB，约 30s）
```

依赖装在隔离 venv 里，不要污染系统 Python。u2net 模型缓存在 `~/.rembg/models/`，之后无需重下。

## 流程

1. **分割**：`remove(img, session=new_session('u2net'), alpha_matting=True,
   alpha_matting_foreground_threshold=240, alpha_matting_background_threshold=10,
   alpha_matting_erode_size=6)` —— alpha_matting 能保住头发丝边缘。
2. **多主体择一**：画面里常有多个角色（人 + 宠物/同伴）。对 α 通道做
   `scipy.ndimage.label` 连通域，打印每块的 `area / bbox / h / w`，取**纵向跨度最大**的一块
   （人物通常最高）；单像素噪点块直接忽略。
3. **纵向宽度剖面**：按身高 20 等分，打印每段的 `width` 与 `fill`，据此判断结构。
   例：动森人物头占 0–45%、颈 45–55%、肩臂 55–75%、躯干到 100%。
   真人比例不同，务必实际打印后再决定裁到哪。
4. **裁上半身**：从头顶取到身高的 N%（证件照一般取到胸下/手臂下方，约 0.75–0.8；
   真人半身像常取 0.5–0.55）。
5. **规整画布**：缩放到目标框（如 480×600 = 4:5），**底部对齐**居中粘贴，
   透明底。证件照/头像位底部对齐比居中更像照片。

## 看不到图时的自检（关键）

会话里如果读图被过滤，用 ASCII 把 α 通道打出来，30 行 × 40 字符足够判断轮廓对不对：

```python
rows, cols = 30, 40
m = block.mean()/255
' ' if m<0.15 else '.' if m<0.4 else '*' if m<0.75 else '#'
```

看三件事：顶是不是头（上窄中宽）、脖子有没有收窄、底部是不是肩/手臂而不是被拦腰截断。
一眼看不出「人头 + 肩膀」就别交，回到第 3 步调比例。

## 落到前端

- PNG 放进 `public/`，用绝对路径 `/assets/...` 引用（Vite 静态资源）。
- 替换 SVG 头像组件时：`<img>` 加 `object-fit: contain`，
  再补 `filter: drop-shadow(...)`，抠图才不会像浮在纸上的贴纸。
- 被替换掉的 SVG 组件文件先留着别删，用户可能要回退。

## 坑

- vite `dev` / `build` 在沙箱里会因 `rm` 被拦截而失败（报 `emptyDir` 或
  `loadCachedDepOptimizationMetadata`）。重跑时放行沙箱即可，不是代码问题。
- rembg 首次跑的进度条会刷满屏，用 `grep -v "%|"` 过滤输出。

