story-cover

|

Skill file

Preview skill file
---
name: story-cover
version: 1.0.0
description: |
  小说封面生成。根据书名、作者名自动分析题材风格,调用 GPT-Image-2 直接生成含标题和署名的专业级网文封面。
  触发方式:/story-cover、/封面、「帮我做个封面」「生成封面图」「做个小说封面」「封面设计」
metadata:
  openclaw:
    requires:
      env:
        - GPT_IMAGE_API_KEY
      bins:
        - curl
        - jq
        - base64
    primaryEnv: GPT_IMAGE_API_KEY
    source: https://github.com/worldwonderer/oh-story-claudecode
---

# story-cover:小说封面生成

你是小说封面设计师。根据书名和题材,调用 GPT-Image-2 一次性生成包含书名和作者名的完整封面。

**核心原则:封面是读者的第一印象,一眼传达题材和氛围。**

---

## 环境变量

| 变量 | 必填 | 默认 | 说明 |
|:-----|:----:|:-----|:-----|
| `GPT_IMAGE_API_KEY` | ✅ | — | OpenAI 或兼容代理的 API Key |
| `GPT_IMAGE_BASE_URL` | | `https://api.openai.com/v1` | 兼容代理时改这个 |
| `GPT_IMAGE_MODEL` | | `gpt-image-2` | 仅在测试新模型时覆盖 |
| `GPT_IMAGE_SIZE` | | `1024x1536` | gpt-image-2 要求两边为 16 倍数、比例 ≤ 3:1 |
| `BOOK_DIR` | ✅ | — | 输出目录,建议 `./covers/<书名>` |
| `REF_IMAGE` | | — | 参考图本地路径或 URL;设置后走 `images/edits` 图生图 |

> 备注:`gpt-image-2` 始终返回 base64,请求体不要带 `response_format`(旧 DALL-E 参数,gpt-image 系列不支持)。

---

## 生成流程

### Step 1:收集信息

必填:书名、作者名(笔名)、目标平台、输出目录 `BOOK_DIR`(建议 `./covers/<书名>`,调用前 export)
选填:参考图 `REF_IMAGE`(本地路径或 URL,设置后切换到图生图)、风格偏好、尺寸(默认竖版 1024x1536)

**根据目标平台确定封面风格**,加载 [references/cover-styles.md](references/cover-styles.md) 获取详细平台和题材风格。

### Step 1.5:题材判定

扫描书名(必要时简介)中的关键词,对照 [references/cover-styles.md](references/cover-styles.md) 的「题材推断规则」表选定题材。

- 单题材命中 → 直接采用
- 多题材命中 → 按优先级取一:仙侠 > 西幻 > 古言 > 现言 > 都市 > 悬疑 > 科幻 > 历史 > 灵异 > 轻小说
- 零命中 → 默认 `都市`

### Step 2:构建提示词

提示词 = **文字层** + **风格层** + **画面层**,全部用英文编写。

#### 文字层:书名 + 作者名字体设计

在提示词中直接包含中文书名和作者名,GPT-Image-2 可直接渲染。**重点描述字体风格**:

```
Title text '书名' at top center in [书名字体风格].
Author name '作者名' at bottom center in [作者名字体风格].
```

#### 书名字体风格

| 题材 | 描述关键词 |
|:-----|:-----------|
| 玄幻/仙侠 | `bold golden brush calligraphy with metallic glow and sharp strokes` |
| 都市 | `modern bold sans-serif with metallic silver finish` |
| 古言/宫斗 | `elegant golden traditional Kai script with ornate decoration` |
| 现言/甜宠 | `soft rounded handwritten style in white with pink glow` |
| 悬疑/推理 | `distorted bold cracked letters in blood red` |
| 科幻/末世 | `neon glowing futuristic font in electric blue` |
| 西幻 | `metallic embossed fantasy lettering with glow effect` |
| 历史/军事 | `heavy stone-carved seal script in deep red` |
| 灵异/恐怖 | `eerie dripping handwritten font in sickly green` |
| 轻小说 | `colorful cartoon outlined bubbly font` |

#### 作者名字体风格(重点:作者名必须精心设计,不能只是"小字")

作者名虽小,但是封面专业感的关键。必须指定:**字体 + 颜色 + 装饰元素**,让作者名与书名风格呼应但不抢焦点。

| 题材 | 作者名风格提示词 |
|:-----|:----------------|
| 玄幻/仙侠 | `small refined white serif text with faint golden glow, flanked by delicate cloud-scroll ornaments on both sides, resting on a thin horizontal gold line` |
| 都市 | `small clean white modern text with subtle drop shadow, positioned above a thin silver horizontal divider line` |
| 古言/宫斗 | `small elegant dark red traditional text inside a thin golden rectangular border frame with corner decorations` |
| 现言/甜宠 | `small soft pink-white handwritten text with a tiny heart motif on the left side, light sparkle effect` |
| 悬疑/推理 | `small pale grey text with slight blur effect, almost hidden in the shadows, a thin cracked line underneath` |
| 科幻/末世 | `small crisp white monospace text with subtle cyan scanline overlay, flanked by small geometric brackets` |
| 西幻 | `small bronze medieval script text with aged parchment texture, enclosed in a small decorative shield or banner shape` |
| 历史/军事 | `small dignified white Song typeface text above a double horizontal line in dark red` |
| 灵异/恐怖 | `small faded grey-green text slightly tilted, with a thin dripping ink line above` |
| 轻小说 | `small playful rounded white text with pastel color outline, tiny star decorations on both sides` |

**作者名通用规则**:
- 大小:`small`(不能太大抢书名焦点,也不能太小看不清)
- 位置:`at bottom center`,与画面底部保持适当间距
- 必须有装饰元素:线条/边框/小图标/光效中至少一种
- 颜色与背景形成对比但不刺眼

#### 风格层:平台风格

平台风格的描述关键词统一来自 [references/cover-styles.md](references/cover-styles.md) 的「平台风格」节,按目标平台直接取对应关键词串使用,不在本文件维护副本以免与参考文件漂移。

#### 画面层:题材 + 构图

从 [references/cover-styles.md](references/cover-styles.md) 读取题材对应的风格标签、色彩、人物、背景描述。

构图变体(首次输出 2-3 个方案):

| 方案 | 构图 | 适合题材 |
|:-----|:-----|:---------|
| A | 人物特写 + 场景 | 全题材通用 |
| B | 全身像 + 动态姿势 | 玄幻、都市、西幻 |
| C | 纯场景/氛围图 | 悬疑、科幻、历史 |

#### 完整提示词模板

```
Chinese web novel cover design, [平台风格].
Title text '{书名}' at top center in [书名字体风格].
Author name '{作者名}' at bottom center in [作者名字体风格 — 从上表选择].
[题材风格标签]. [人物描述]. [背景描述].
[色彩指令]. [光效指令].
Professional book cover, high detail digital painting, portrait 2:3 ratio, no watermark
```

#### 提示词技巧(实测验证)

- 人物描述越具体越好:服饰、姿态、发型、表情、道具每个维度都指定
- 背景分层:前景(人物)→ 中景(场景)→ 远景(氛围)
- 光效是指定光源方向 + 颜色(如 `dramatic golden light from above`)
- 用 `digital painting style` 而非 `photo`,避免真人照片感

### Step 3:调用 API 并保存

`gpt-image-2` 始终返回 base64,请求体不要带 `response_format`。`$PROMPT` 为 Step 2 拼出的完整提示词。

两种调用方式二选一:未设置 `REF_IMAGE` → 走「文生图」;设置了 → 走「图生图」。

#### 文生图(默认)

```bash
set -euo pipefail
: "${GPT_IMAGE_API_KEY:?请设置 export GPT_IMAGE_API_KEY=你的key}"
: "${PROMPT:?请先 export PROMPT=Step 2 拼好的完整提示词}"
BASE_URL="${GPT_IMAGE_BASE_URL:-https://api.openai.com/v1}"
MODEL="${GPT_IMAGE_MODEL:-gpt-image-2}"
SIZE="${GPT_IMAGE_SIZE:-1024x1536}"
BOOK_DIR="${BOOK_DIR:?请先 export BOOK_DIR=./covers/<书名>}"

mkdir -p "$BOOK_DIR/封面"

# 自增版本号,避免覆盖之前生成的封面
i=1
while [ -f "$BOOK_DIR/封面/封面_v${i}.png" ]; do i=$((i+1)); done
OUT="$BOOK_DIR/封面/封面_v${i}.png"
RESP=$(mktemp)
trap 'rm -f "$RESP"' EXIT

# 用 jq 拼 JSON 体,避免 PROMPT 里的引号/换行/中文把 shell 字符串撑破
BODY=$(jq -n \
  --arg m "$MODEL" \
  --arg p "$PROMPT" \
  --arg s "$SIZE" \
  '{model:$m, prompt:$p, size:$s}')

curl -fsS --max-time 180 --retry 2 --retry-delay 5 \
  "$BASE_URL/images/generations" \
  -H "Authorization: Bearer $GPT_IMAGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$BODY" > "$RESP"

# API 出错时早退,避免把 error JSON 当成 base64 写成损坏 PNG
if jq -e '.error' "$RESP" >/dev/null 2>&1; then
  echo "API error:" >&2
  jq '.error' "$RESP" >&2
  exit 1
fi

# `// empty` 让缺失字段输出空串而非 "null",配合下面的 -s 检查避免写出 3 字节假 PNG
jq -er '.data[0].b64_json // empty' "$RESP" | base64 --decode > "$OUT"
[ -s "$OUT" ] || { echo "empty or malformed output: $OUT" >&2; head -c 300 "$RESP" >&2; exit 1; }

# 落地提示词副本,方便迭代时基于上一次微调
printf '%s\n' "$PROMPT" > "${OUT%.png}.prompt.txt"

file "$OUT"
ls -lt "$BOOK_DIR/封面/"
```

#### 图生图(提供参考图时)

`/v1/images/edits` 走 `multipart/form-data`,**不能** 用 `Content-Type: application/json`。文本字段用 `--form-string`(避免 `@` 被误判为文件引用),图片字段用 `-F image=@path`。

```bash
set -euo pipefail
: "${GPT_IMAGE_API_KEY:?请设置 export GPT_IMAGE_API_KEY=你的key}"
: "${PROMPT:?请先 export PROMPT=Step 2 拼好的完整提示词}"
BASE_URL="${GPT_IMAGE_BASE_URL:-https://api.openai.com/v1}"
MODEL="${GPT_IMAGE_MODEL:-gpt-image-2}"
SIZE="${GPT_IMAGE_SIZE:-1024x1536}"
BOOK_DIR="${BOOK_DIR:?请先 export BOOK_DIR=./covers/<书名>}"
REF_IMAGE="${REF_IMAGE:?请先 export REF_IMAGE=本地路径或 URL}"

mkdir -p "$BOOK_DIR/封面"

# 自增版本号
i=1
while [ -f "$BOOK_DIR/封面/封面_v${i}.png" ]; do i=$((i+1)); done
OUT="$BOOK_DIR/封面/封面_v${i}.png"
RESP=$(mktemp)
REF_TMP=""
trap '[ -n "$REF_TMP" ] && rm -f "$REF_TMP"; rm -f "$RESP"' EXIT

# URL 先下载到临时文件,本地路径直接用。用裸 mktemp 以保证 macOS/Linux 行为一致。
case "$REF_IMAGE" in
  http://*|https://*)
    REF_TMP=$(mktemp)
    curl -fsSL --max-time 60 -o "$REF_TMP" "$REF_IMAGE"
    REF_LOCAL="$REF_TMP"
    ;;
  *)
    [ -f "$REF_IMAGE" ] || { echo "参考图不存在: $REF_IMAGE" >&2; exit 1; }
    REF_LOCAL="$REF_IMAGE"
    ;;
esac

curl -fsS --max-time 240 --retry 2 --retry-delay 5 \
  "$BASE_URL/images/edits" \
  -H "Authorization: Bearer $GPT_IMAGE_API_KEY" \
  --form-string "model=$MODEL" \
  --form-string "size=$SIZE" \
  --form-string "prompt=$PROMPT" \
  -F "image=@$REF_LOCAL" > "$RESP"

if jq -e '.error' "$RESP" >/dev/null 2>&1; then
  echo "API error:" >&2
  jq '.error' "$RESP" >&2
  exit 1
fi

# `// empty` 让缺失字段输出空串而非 "null",配合 -s 检查避免写出 3 字节假 PNG
jq -er '.data[0].b64_json // empty' "$RESP" | base64 --decode > "$OUT"
[ -s "$OUT" ] || { echo "empty or malformed output: $OUT" >&2; head -c 300 "$RESP" >&2; exit 1; }

printf '%s\n' "$PROMPT"    > "${OUT%.png}.prompt.txt"
printf '%s\n' "$REF_IMAGE" > "${OUT%.png}.ref.txt"

file "$OUT"
ls -lt "$BOOK_DIR/封面/"
```

### Step 4:质量检查 + 迭代

| 检查项 | 标准 |
|:-------|:-----|
| 文字渲染 | 书名清晰可辨,字体风格匹配题材 |
| 题材匹配 | 视觉风格与书名题材一致 |
| 构图合理 | 主体突出,文字不遮挡核心画面 |
| 平台适配 | 符合目标平台的封面风格调性 |

不满意时调整方向:更换构图、调整色调、换字体风格、换平台风格。

---

## 参考资料

| 文件 | 何时加载 |
|:-----|:---------|
| [references/cover-styles.md](references/cover-styles.md) | 题材→视觉风格映射、平台风格详情、提示词模板 |

---

## 语言

- 跟随用户的语言回复,用户用什么语言就用什么语言回复
- 中文回复遵循《中文文案排版指北》

Source

Creator's repository · worldwonderer/oh-story-claudecode

View on GitHub

Security

Security checks in progress
Results will appear here once audits complete
What this skill can do
Reads your filesConnects to the internetRuns code on your machine
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk