# Memoji Sticker Pack

> 从一张人物照片生成一套 Apple Memoji 风格（拟我表情）的表情贴纸包。当用户想"把这张照片/自拍做成 Memoji 表情包 / 拟我表情包 / 表情贴纸 / nimoji / Q 版头像表情"，或给一张人脸照片并想要一组不同表情（微笑/大笑/哭/惊讶/比心/点赞等）的卡通贴纸时，使用本技能——即使用户没明确说"Memoji"这个词，只要意图是"照片→一套人物表情贴纸"，也应触发。也支持只生成单张 Memoji 风格头像。不用于：视频/动态表情、OCR、给已有图做裁剪压缩水印等非生成式编辑。

- Skill: `cookaihq/memoji-sticker-pack` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add cookaihq/memoji-sticker-pack`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cookaihq/memoji-sticker-pack/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cookaihq (https://skillmd.com/u/cookaihq)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/cookaihq/memoji-sticker-pack

---


# memoji-sticker-pack

## 这个技能做什么

输入**一张人物照片**，产出一套 **Apple Memoji 风格**的表情贴纸包：先把照片转成一张「基准 Memoji」头像锁定长相，再以它为参考逐个生成多个表情（默认 16 个），最后给出透明底 PNG + 可浏览的 `index.html` 画廊。

本技能是**编排器**：自己不调生成/上传 API，而是编排两个已安装的兄弟技能——用 **image-2 (gpt-image-2)** 的 `create_task.sh` 生成图（复用它的 key 链、轮询、下载、401 兜底），用 **upload-for-url** 的 `upload.py` 把参考图上传到 foxapi 文件接口换成 72h 公网 URL。**参考图统一走「上传取 URL」，不再内联 base64 data URI**：传给生成接口的 `image_urls` 全是 foxapi CDN 链接。两者共用同一把 `X_API_KEY`、同一 host（`api.foxapi.cc`，可用 `FOXAPI_BASE_URL` 覆盖）。

## 何时使用

- "把这张照片/自拍做成 Memoji 表情包 / 拟我表情包 / 表情贴纸包"
- "用我这张照片生成一组不同表情的卡通贴纸"
- "做个 Q 版头像表情 / nimoji"
- 只要一张 Memoji 风格头像（用 `--mode single`）

## 何时不要用

- 视频 / 动态 Memoji / GIF
- OCR、文档解析
- 对已有图做裁剪、压缩、加水印等非生成式编辑

## 依赖

- 需要生成图片时，已安装 **image-2** 技能（`~/.claude/skills/image-2*/scripts/create_task.sh`）。
- 需要上传输入图或基准图时，已安装 **upload-for-url** 技能（`~/.claude/skills/upload-for-url*/scripts/upload.py`）。只有 `--base-url ... --mode single` 完全不需要这两个兄弟 Skill。
- 配好 **foxapi.cc 的 key**（生成与上传共用，环境变量 `X_API_KEY`，或工作目录下 `.env` / `.env.local`）。
  - ⚠️ 用 `--use-local-key` 时，image-2 读 `~/.config/image-2/.env`、upload-for-url 读 `~/.config/upload-for-url/.env`（本仓约定每个 skill 各自持久化配置）。若只在其中一个配了 key，另一步会因缺 key 失败——**最省事是把 key 放进程 env 或 `$PWD/.env`，两步都能读到**。
- macOS 自带 `sips`（用于缩图；缺失时回退 `ffmpeg`）。

## ⚠️ 成本与确认（重要）

每张贴纸都是一次 `gpt-image-2` 调用、**会消耗 foxapi 积分**：

- 不复用基准图时，pack 无重试 = **1（基准）+ N（表情）** 次调用（默认 N=16 → 17 次）。
- 默认每次失败生成最多重试一次（含基准），因此最大 = **2 + 2N**；`--no-retry` 时等于无重试次数。
- 不复用基准图时，`single` 无重试 1 次、最大 2 次。
- 复用 `--base-url` 时，pack 无重试 N 次、最大 2N 次；single 不调用生成。
- 另有**文件上传调用**（转存参考图到 foxapi 文件接口，**非生成调用**）：正常 pack = 2 次、single = 1 次；复用基准图时 pack = 1 次、single = 0 次。上传是否计费以 foxapi 侧为准；本技能不额外统计。

**因此运行真正生成前，必须：**

1. 先跑 `--plan` 拿到准确的调用次数。
2. 把"将生成什么 + 预计调用次数 + 会消耗积分"摘要给用户，**等用户明确确认后**再真正运行。
3. 失败重试默认开启（用户在设计时已授权）；若用户不希望重试，加 `--no-retry`。

## 使用流程（Agent 按此执行）

> 下面命令里的 `$SKILL_DIR` 指**本技能自身所在目录**（含本 SKILL.md 的目录）。Claude Code 触发技能时会告知它的 base directory；执行前先 `SKILL_DIR="<该目录>"`，或直接把 `$SKILL_DIR` 换成绝对路径。脚本内部对 `cutout.py`/`build_gallery.py` 的引用是自定位的（`dirname "$0"`），无需另配。

### 1. 收集输入

- 必须拿到一张人物照片（本地路径 / 公网 URL / data URI），或用 `--base-url` 提供已有基准图 URL。新照片会自动缩图并上传到 foxapi 换 URL，连传入的公网 URL 也会重新转存以统一。
- 可选：人物名/包名（`--name`）、输出目录（`--outdir`）、只要单张（`--mode single`）、自定义/裁剪表情数（`--count` / `--expressions`）。

### 2. 预览成本，等确认

```bash
bash "$SKILL_DIR/scripts/gen_pack.sh" \
  --image "<照片路径>" --name "<名字>" --plan
```

把输出里的调用次数、输出目录、表情清单转述给用户，明确"会消耗积分"，**等用户确认**。

### 3. 真正生成

```bash
bash "$SKILL_DIR/scripts/gen_pack.sh" \
  --image "<照片路径>" --name "<名字>"
```

脚本会：预处理照片 → 生成 `base.png` → 逐个生成 `NN-<slug>.png`（透明底）→ 写 `manifest.json` + `index.html`。每个表情失败自动重试一次再跳过，结束时汇总失败项。

### 4. 展示结果

- 生成完用 `as_open_url` 打开 `<outdir>/index.html` 给用户看整套（画廊用棋盘格背景显示透明区域）。
- 转述成功/失败数；若有失败项，告诉用户可用 `--expressions "<slug>:<描述>"` 单独补跑。

## 关键参数

| 参数 | 说明 |
|---|---|
| `--image PATH` | 与 `--base-url` 二选一。本地路径 / 公网 URL / data URI |
| `--name NAME` | 人物名/包名，影响输出目录 `./memoji-<name>/` 与画廊标题 |
| `--outdir DIR` | 自定义输出目录 |
| `--mode pack\|single` | `pack`=整套(默认)，`single`=只出基准头像 |
| `--count N` | 只取前 N 个表情 |
| `--expressions "slug:描述;..."` | 覆盖默认表情（英文描述效果最好） |
| `--resolution WxH` | 贴纸分辨率，默认 `1024x1024` |
| `--no-retry` | 关闭失败重试 |
| `--base-url URL` | 与 `--image` 二选一。复用已有基准图，跳过基准生成 |
| `--use-local-key` | 允许读 `~/.config/image-2/.env` 里的 key |
| `--plan` | 只打印计划与调用次数，不生成、不消耗积分 |

## 默认 16 表情

微笑、大笑、狂笑、大哭、流泪、惊讶、比心、点赞、爱心眼、生气、瞪眼、思考、眨眼、翻白眼、捂脸、OK 手势。
（完整 slug 与英文描述见 `scripts/gen_pack.sh` 顶部的 `DEFAULT_EXPRESSIONS`，那是表情集的唯一真源。）

## 一致性是怎么保证的

16 个表情**不是各自从原始照片重画**（那样每张脸会漂移），而是都以**同一张基准 Memoji**为参考、只改表情/动作。基准图由脚本缩到 ≤640px 后**上传到 foxapi 换成一个 URL**，该 URL 复用给每次调用，所以全套是同一张脸。

## 输出结构

```
memoji-<name>/
  base.png              # 基准头像
  01-smile.png … NN-*.png   # 各表情，透明底 PNG
  manifest.json         # 名称、基准图、表情列表映射
  index.html            # 画廊（浏览器/as_open_url 打开）
  .log-*.txt            # 每次调用的日志（排错用）
```

## 排错

- **"未找到 image-2 的 create_task.sh"**：先装 image-2 技能。
- **"未找到 upload-for-url 的 upload.py"**：先装 upload-for-url 技能（参考图上传换 URL 靠它）。
- **上传失败**：看 `<outdir>/.log-upload.txt`。
  - `403` + 响应体 `error code: 1010` = Cloudflare 拦截了非浏览器 UA；upload-for-url 的 `client.py` 已内置浏览器 UA 修复，若仍出现说明装的是旧版 upload-for-url，更新它。
  - `401` = key 无效/缺失；确认 `X_API_KEY` 可被 upload-for-url 读到（见「依赖」里 `--use-local-key` 的配置目录说明）。
  - `413` = 文件过大；脚本已缩到 ≤768px，正常不会触发。
- **基准生成就失败**：多半是 key/积分问题，看 `.log-base.txt`，按 image-2 的报错处理（401 key 无效 / 402 余额不足 / 429 限流）。
- **个别表情总失败**：手势类（OK/点赞/比心）偶尔不稳，可改 `--expressions` 换个描述单独补跑。

