用 ChatGPT 写一本 12 页的儿童绘本故事,用 Midjourney V8.2 的 Edit 模型让同一个角色在每一页保持一致,最后用 Python 脚本把插图和文字自动排版成可打印的 PDF。
先看清成品
成品是一本 A4 横版、300 dpi 的 PDF 绘本《阿木第一次看见雪》:主角是一只戴红围巾的小棕熊,12 页插图里外形保持一致,每页下方配一到两句文字。角色一致性靠“角色设定图 + Edit 模型参考图”实现。排版脚本已在本地实际运行,生成的 PDF 页数和版式经过检查。
做完之后你会得到什么?
| 成果 | 说明 |
|---|---|
| 故事脚本 | 12 页,每页一句画面描述 + 一到两句正文 |
| 角色设定图 | 一张正面、侧面、背面的角色参考 |
| 12 张插图 | 同一角色、同一画风 |
| PDF 绘本 | A4 横版 300 dpi,可直接打印或发给印刷厂 |
需要准备哪些环境?
| 项目 | 要求 | 说明 |
|---|---|---|
| Midjourney 订阅 | 任意付费档 | 网页端 midjourney.com 或官方 Discord |
| Python | 3.10 或更高 | 运行本文的后期处理脚本 |
| Pillow | pip install pillow |
图片裁剪、拼接、排版 |
| 中文字体 | 系统自带即可 | 脚本会自动寻找苹方、微软雅黑或 Noto CJK |
Edit 模型目前只能用于 V8.1 和 V8.2。
注意:Midjourney 服务条款禁止用自动化工具访问或生成内容,所以本文所有生成步骤都在网页或 Discord 里手动完成,脚本只处理已经下载到本地的图片。
第一步:怎样写出适合画的故事?
1. 发送故事提示词
写一个 12 页的儿童绘本故事,读者 3-6 岁。
主角:一只叫阿木的小棕熊,戴红色围巾,好奇又有点胆小。
主题:第一次看见雪,从害怕到喜欢。
输出一个表格,列为:页码 | 正文(每页不超过 30 个字)| 画面描述(英文,30 词以内,只描述场景和动作,不描述角色外形)
要求:每页画面要有明显变化(远景、近景、特写交替),最后一页温暖收尾。
2. 检查结果
画面描述列不要出现角色外形描写,外形全部交给参考图,否则文字和参考图会互相打架。
把结果保存为两份文件:
picture-book/
├── story.md # ChatGPT 输出的完整表格
├── book.txt # 排版用:每行“图片文件名|正文”
├── character/
│ └── amu-sheet.png # 角色设定图
├── pages/
│ ├── p01.png
│ ├── ...
│ └── p12.png
├── make_book.py
└── book.pdf
第二步:怎样做出“角色设定图”?
角色一致性的关键是先有一张清晰、干净的角色参考图。
1. 生成设定图
character sheet of a small brown bear cub wearing a red knitted scarf, front view, side view and back view, standing, plain white background, soft watercolor children's book illustration, gentle colors --ar 3:2 --s 100
2. 挑选标准
| 检查项 | 要求 |
|---|---|
| 背景 | 纯色,无杂物 |
| 特征 | 围巾颜色、耳朵形状、体型清楚可辨 |
| 一致性 | 三个视角是同一只熊 |
| 画风 | 就是你想要的绘本画风 |
不满意就多跑几次,这一步值得多花时间。
注意:角色设定图里的三个视角如果不像同一只熊,后面每一页都会继承这个问题。
第三步:怎样逐页生成并保持角色一致?
1. 把设定图作为 Edit 参考
网页端:点输入框的图片图标,把 amu-sheet.png 拖到 Attach to prompt 区域,可以点锁形图标固定,后面每条提示词都会带上它。
Discord:在提示词末尾加 --edit 和设定图的网址。
2. 每页的提示词结构
this bear cub [画面描述], soft watercolor children's book illustration, gentle colors --ar 3:2
例如第 1 页:
this bear cub looking out of a small wooden window at the first snowflakes falling, cozy room, morning light, soft watercolor children's book illustration, gentle colors --ar 3:2
| 要点 | 原因 |
|---|---|
| 用 “this bear cub” 指代 | 让模型把参考图当成主角 |
| 不写外形 | 外形以参考图为准 |
显式写 --ar 3:2 |
Edit 模型默认匹配第一张参考图的比例,不会自动套用你的默认比例设置 |
| 固定画风尾巴 | 12 页画风统一 |
3. 多角色页面
第 8 页出现了小兔子朋友。可以再附一张小兔子的设定图(最多 4 张参考图),提示词里分别描述“the bear cub”和“the rabbit”。
官方建议:如果两个角色的特征经常混在一起,可以把两个角色合成到一张参考图里。
4. 局部修正
某一页只有围巾颜色不对,不必重画。用 Editor 选中围巾区域,写“make the scarf red”即可。
5. 下载并命名
按页码存为 pages/p01.png 到 pages/p12.png。
第四步:怎样自动排版成 PDF?
1. 准备 book.txt
每行一页,用竖线分隔图片文件名和正文:
p01.png|小熊阿木第一次看见雪,它趴在窗边,眼睛睁得圆圆的。
p02.png|“这是什么?白白的,软软的。”阿木小声问。
p03.png|妈妈说:“这是雪。要不要出去摸一摸?”
2. 脚本 make_book.py
"""把绘本插图和文字排成 PDF。
book.txt 每页一行,格式:图片文件名|这一页的文字
用法:python make_book.py 插图目录 book.txt 输出.pdf
"""
import sys
import textwrap
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont, ImageOps
PAGE = (2480, 1754) # A4 横版 300dpi
FONT_CANDIDATES = ("/System/Library/Fonts/PingFang.ttc", "C:/Windows/Fonts/msyh.ttc",
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc")
def font(size):
for c in FONT_CANDIDATES:
if Path(c).exists():
return ImageFont.truetype(c, size)
raise SystemExit("找不到中文字体,请修改 FONT_CANDIDATES")
def page(img_path, text):
pg = Image.new("RGB", PAGE, "white")
art = Image.open(img_path).convert("RGB")
# contain 会等比缩放到框内,原图偏小时也会放大填满
art = ImageOps.contain(art, (PAGE[0] - 200, PAGE[1] - 520), method=Image.LANCZOS)
pg.paste(art, ((PAGE[0] - art.width) // 2, 100))
d = ImageDraw.Draw(pg)
f = font(64)
lines = textwrap.wrap(text, width=30) # 中文按字数折行,每行约 30 字
y = 100 + art.height + 80
for line in lines:
w = d.textlength(line, font=f)
d.text(((PAGE[0] - w) / 2, y), line, font=f, fill="#333333")
y += 96
return pg
def main(img_dir, script, out):
pages = []
for i, raw in enumerate(Path(script).read_text(encoding="utf-8").splitlines(), 1):
if not raw.strip():
continue
name, _, text = raw.partition("|")
p = Path(img_dir) / name.strip()
if not p.exists():
raise SystemExit(f"第 {i} 行的图片不存在:{p}")
pages.append(page(p, text.strip()))
pages[0].save(out, save_all=True, append_images=pages[1:], resolution=300)
print(f"已生成 {out},共 {len(pages)} 页")
if __name__ == "__main__":
main(*sys.argv[1:4])
ImageOps.contain 等比缩放插图填满页面上方,原图偏小时也会放大;文字自动按约 30 个字折行并居中。
3. 运行
pip install pillow
python make_book.py pages book.txt book.pdf
期望输出:
已生成 book.pdf,共 12 页
4. 检查结果
| 检查项 | 通过标准 |
|---|---|
| 页数 | 12 页 |
| 版式 | 插图在上、文字在下,居中 |
| 文字 | 中文正常显示,没有方框 |
| 清晰度 | 放大到 100% 插图不明显发虚 |
| 顺序 | 和故事顺序一致 |
本文用两页测试图实际运行过,输出 2 页 PDF,版式符合预期。
出问题时该怎么调?
1. 角色每页长得不一样
依次检查:参考图是否每页都附上了;提示词里是否又写了外形描述;画风尾巴是否完全一致。
还不稳定时,可以把已经满意的某一页插图也加入参考图,和设定图一起用。
2. 参考图的背景也被带进画面
设定图背景不够干净时会出现这个问题。重做一张纯白背景的设定图,或在提示词里明确写出新场景。
3. 想让画面更贴近文字描述
官方说明在 Edit 模型中加 --raw 可以减少额外的创意发挥,让结果更贴近提示词。
4. PDF 里文字是方框
脚本没找到中文字体。打开 make_book.py,把你系统里的中文字体路径加到 FONT_CANDIDATES 最前面。
5. 印刷厂说分辨率不够
V8.1 和 V8.2 可用 --hd 直接生成 2048 像素的插图。Edit 模型兼容 --hd。
注意:Edit 模型目前不能和
--tile一起用,生成的图也暂不支持 Remix。
商用前要确认什么?
按 Midjourney 服务条款,你生成的图片归你所有,退订后仍然有效,但有几个例外:
| 情况 | 规则 |
|---|---|
| 公司或其员工,公司年收入超过 100 万美元 | 必须订阅 Pro 或 Mega 才拥有生成图片的权利 |
| 放大(Upscale)别人生成的图 | 图片仍归原作者 |
| 提示词里写了真实品牌、角色、名人 | 可能侵犯第三方权利,条款不会替你承担 |
注意:各国对 AI 生成内容能否获得版权保护的规定不同,用于商标、出版等重要场景前请咨询律师。
常见问题怎么处理?
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 比例不是 3:2 | Edit 模型跟随第一张参考图比例 | 每条提示词显式加 --ar 3:2 |
| Discord 提示图片无效 | 参考图不是在线网址 | 先上传到 Discord 再复制链接 |
| 两个角色特征混淆 | 参考图分开、描述不清 | 合并成一张参考图,或分别写清楚 |
| 脚本报“图片不存在” | book.txt 文件名写错 | 核对报错行号和文件名大小写 |
| 文字超出页面 | 某页正文太长 | 控制每页 30 字以内,或把字号改小 |
| 打印颜色偏暗 | 屏幕和印刷色彩差异 | 先打一页样张 |
项目资源
建议先只做 3 页:一张角色设定图加 3 页插图,检查角色是否一致,再跑一次排版脚本看 PDF 效果。
3 页都满意后再补齐 12 页,这样返工成本最低。