小說封面生成。根據書名、作者名自動分析題材風格,呼叫 GPT-Image-2 直接生成包含標題與署名的專業級網文封面。觸發方式:/story-cover、/封面、「幫我做個封面」、「生成封面圖」、「做個小說封面」、「封面設計」。
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 |
目標比例提示(番茄 3:4→768x1024,預設 2:3→1024x1536)。官方 gpt-image-2 支援任意 16 倍數尺寸(比例≤3:1),但很多中轉代理會忽略 size,按預設返回約 2:3(已實測)——平台尺寸不靠它,由 Step 3.5 兜底 |
|
UPLOAD_SIZE |
— | 平台固定上傳像素(番茄 600x800);設定後 Step 3.5 居中裁切+縮放出上傳版(不變形、不依賴出圖尺寸) |
|
BOOK_DIR |
✅ | — | 輸出目錄,建議 ./covers/<書名> |
REF_IMAGE |
— | 參考圖本地路徑或 URL;設定後走 images/edits 圖生圖 |
生成流程
Step 1:收集資訊
必填:書名、作者名(筆名)、目標平台、輸出目錄 BOOK_DIR(建議 ./covers/<書名>,呼叫前 export)
選填:參考圖 REF_IMAGE(本地路徑或 URL,設定後切換到圖生圖)、風格偏好、尺寸
書名與筆名是封面必需資訊:缺任一必須先用 AskUserQuestion 詢問使用者補全,不得編造或留空。
按目標平台確定封面尺寸:番茄上傳 600×800 是 3:4(不是 2:3),出圖比例不對、平台二次裁切就會切掉書名/筆名。
| 平台 | 上傳尺寸 | 比例 | 生成 GPT_IMAGE_SIZE(盡量) |
|---|---|---|---|
| 番茄小說 | 600×800 | 3:4 | 768x1024 |
| 其他平台(預設豎版) | 按平台規格 | 2:3 | 1024x1536 |
export GPT_IMAGE_SIZE 給予目標比例(官方按它出圖,很多代理會忽略、返回約 2:3);平台有固定上傳像素再 export UPLOAD_SIZE(番茄 600x800)。平台尺寸最終由 Step 3.5 居中裁切+縮放保證,不依賴代理認不認 size。 平台與題材風格見 references/cover-styles.md。
Step 1.5:題材判定
掃描書名(必要時簡介)中的關鍵字,對照 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 讀取題材對應的風格標籤、色彩、人物、背景描述。
構圖變體(首次輸出 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 [平台比例:番茄=3:4,預設=2:3] ratio, keep title and author name inside the central safe area away from edges (inner ~85%), no watermark
提示詞技巧(實測驗證)
- 人物描述越具體越好:服飾、姿態、髮型、表情、道具每個維度都指定
- 背景分層:前景(人物)→ 中景(場景)→ 遠景(氛圍)
- 光效是指定光源方向 + 顏色(如
dramatic golden light from above) - 用
digital painting style而非photo,避免真人照片感
Step 3:呼叫 API 並儲存
gpt-image-2 始終返回 base64,請求體不要帶 response_format(舊 DALL-E 參數,gpt-image 系列不支援)。$PROMPT 為 Step 2 拼出的完整提示詞。
兩種呼叫方式二選一:未設定 REF_IMAGE → 走「文生圖」;設定了 → 走「圖生圖」。
文生圖(預設)
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。
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 3.5:匯出平台上傳尺寸(平台有固定像素時)
設定了 UPLOAD_SIZE(番茄 600×800)就把原圖居中裁切+縮放成上傳尺寸——不論出圖是 2:3 還是 3:4 都裁成平台精確像素,不變形,避免平台再裁切掉書名/筆名。原圖保留、另存 _上傳 版:
SRC="${OUT:-$(ls -t "${BOOK_DIR:-.}"/封面/封面_v*.png 2>/dev/null | grep -v _上傳 | head -1)}" # 複用 Step 3 的 $OUT;新 shell 裡從 BOOK_DIR 找最新原圖
TARGET="${UPLOAD_SIZE:-}" # 番茄=600x800;未設則跳過
if [ -n "$TARGET" ] && [ -f "$SRC" ]; then
UP="${SRC%.png}_上傳.png"; W="${TARGET%x*}"; H="${TARGET#*x}"
if command -v magick >/dev/null 2>&1; then M=magick
elif command -v convert >/dev/null 2>&1; then M=convert; else M=""; fi
if [ -n "$M" ]; then
"$M" "$SRC" -resize "${W}x${H}^" -gravity center -extent "${W}x${H}" "$UP" # 縮放填滿後居中裁
elif command -v sips >/dev/null 2>&1; then
cp "$SRC" "$UP"
sw=$(sips -g pixelWidth "$UP" | awk '/pixelWidth/{print $NF}')
sh=$(sips -g pixelHeight "$UP" | awk '/pixelHeight/{print $NF}')
if [ $((sw*H)) -ge $((sh*W)) ]; then sips --resampleHeight "$H" "$UP" >/dev/null
else sips --resampleWidth "$W" "$UP" >/dev/null; fi
sips -c "$H" "$W" "$UP" >/dev/null # sips -c 是 高 寬,居中裁
else
echo "無 magick/convert/sips,跳過;手動把 $SRC 居中裁切+縮放到 $TARGET 再上傳" >&2
fi
[ -f "$UP" ] && file "$UP"
fi
書名/筆名已在提示詞裡留中心安全區,居中裁切不會切到。
Step 4:品質檢查 + 疊代
| 檢查項 | 標準 |
|---|---|
| 文字渲染 | 書名清晰可辨,字體風格匹配題材 |
| 題材匹配 | 視覺風格與書名題材一致 |
| 構圖合理 | 主體突出,文字不遮擋核心畫面 |
| 平台適配 | 符合目標平台的封面風格調性 |
| 平台尺寸 | 比例與平台一致;縮放到上傳尺寸後書名、筆名完整可見、未被裁切 |
不滿意時調整方向:更換構圖、調整色調、換字體風格、換平台風格。
參考資料
| 檔案 | 何時載入 |
|---|---|
| references/cover-styles.md | 題材→視覺風格對映、平台風格詳情、提示詞範本 |
語言
- 跟隨使用者的語言回覆,使用者用什麼語言就用什麼語言回覆
- 中文回覆遵循《中文文案排版指北》






