2026年9月15日 · 阅读 —
做公众号封面,我放弃了让大模型「画」
做公众号封面,我放弃了让大模型「画」

公众号封面的规格,其实很死。
固定 900×383,横版。
标题要一字不差,副标题也是。
整个号还要风格统一,这期和上期不能是两个画风。
你把这套约束丢给多模态大模型,让它「画」一张:
每次生成都要烧 image token,量一大,成本蹭蹭涨。
更头疼的是不可控——模型自由发挥,尺寸会偏,构图会跑,文字位置飘忽。
最恼火的是标题。你写的是「聊聊 AI 测试」,它给你在图上改几个字、加个标签、漏个标点。
封面这种事,文字错一个字都不能忍。
我这次做工具,把生成方式整个换掉了:不用模型画,用代码渲染。
多套内置样式 · 自适应文字排布 · Web 前端 + 命令行双入口 · 可选微信素材上传

🤔 为什么用代码生成,而不是让大模型「画」封面?
市面上很多工具用多模态大模型一键生成封面,看起来省事,但对公众号封面这种强模板、强规范的场景并不合适:
| 痛点 | 多模态生成 | 本工具(HTML 模板渲染) |
|---|---|---|
| 💸 成本 | 每次生成都要消耗 image token / 多模态 token,量一大成本可观 | 零多模态调用,只消耗本地 CPU 渲染,无 token 成本 |
| 📐 跑偏 | 模型自由发挥,尺寸、构图、文字位置常跑偏,出图不可控 | 固定 900×383,严格按模板渲染,绝不跑偏 |
| 🎨 风格 | 每次风格漂移,难以保持一致 | 风格完全可控,同一套 CSS 模板,次次一致 |
| 🏷️ 文字 | 文字内容可能被模型改写、加字、漏字 | 文字精确注入,标题/副标题 100% 就是你写的 |
| ✍️ 自定义 | 改样式要反复调 prompt,玄学调参 | 直接改 HTML/CSS,所见即所得,可无限扩展模板 |
一句话总结:封面是「排版」问题,不是「创作」问题——交给模板引擎精确渲染,而不是让模型自由发挥。省钱、不跑偏、风格稳、好定制。
封面是排版问题,不是创作问题
这是我做完之后最想讲清楚的一点。
公众号封面这种强模板、强规范的场景,本质是个排版活。
标题放哪,副标题放哪,用什么风格,底图长什么样——这些是可穷举、可复现的约束。
它不需要模型「创作」,需要的是把字准确排进去。
我用的方案,是 HTML 模板加本地渲染。
每个封面样式,就是一个独立的 HTML 文件:cover_template_minimal.html、cover_template_paper.html、cover_template_neon.html、cover_template_cosmic.html、cover_template_fresh.html。
一共五套:极简、深空、暖纸、霓虹、清新。
生成的时候,工具把标题和副标题注入到模板里,再用 Playwright 渲染成 900×383 的 PNG。
全程不调多模态模型,不花 image token,只有本地 CPU 在干活。

模板的契约,决定了可扩展性
这些模板文件不是随便画的,它们按一套固定契约工作。
页面里要有 #title、#subtitle 两个元素,可选 #eyebrow 眉题。
提供 window.__coverAfterText__() 这个函数,文字注入之后做自适应排版——标题长了自动缩放,不会溢出。
支持 body.export 这个 class,出图时把外层留白去掉。
有了这个契约,加一个新样式就特别简单:复制一个模板文件,改改 CSS,在 wx_upload_cover.py 里的 TEMPLATES 字典注册个名字。
完事,Web 下拉框里自动多一项。
我实际给每个模板都渲染了预览图,放在 docs/preview/ 下,极简、深空、暖纸、霓虹、清新五张,一眼看出风格差在哪。
- 极简 · 干净留白
- 深空 · 深邃星空
- 暖纸 · 温暖纸质
- 霓虹 · 炫彩霓虹
- 清新 · 自然清爽
✨ 封面样式预览
每个样式都是一个独立的 HTML 模板,按同一套渲染契约工作,可一键切换:
极简 · 干净留白 | 深空 · 深邃星空 |
暖纸 · 温暖纸质 | 霓虹 · 炫彩霓虹 |
清新 · 自然清爽 |
上图为五套内置样式的实际渲染效果。新增样式只需加一个 HTML 模板文件,放到
templates/,在src/wxcover/core.py的TEMPLATES字典注册即可。
两个入口,覆盖两种用法
这工具给了两个运行方式。
命令行,本地快速出图:
uv run python wx_upload_cover.py
会在 output/generated_cover_html/ 生成封面,按配置决定是否上传。
Web 前端,适合日常操作:
uv run python web_server.py
打开 http://127.0.0.1:8765,有个页面可以下拉选标题、选模板、填副标题,还能勾选是否上传、把标题和副标题的显示位置对调。
提交之后日志实时流式打印:生成 PNG → 转 JPEG → 上传,结束显示结果。
选标题用的是下拉框,我内置了 8 个公开通用的占位标题,方便直接试。
依赖很简单,pyproject.toml 里就四个:playwright、requests、Pillow、colorlog。
首次用装一下浏览器内核:
uv sync --locked
playwright install chromium
上传那部分,靠微信官方接口
生成封面只是第一步,发布的时候得传到公众号素材库。
工具调的是微信「新增永久素材」接口。
流程是:get_access_token 拿令牌 → upload_cover_image 上传,返回 media_id 和 img_url。
微信凭据只存在本地 config/config.ini 里,那个文件已经被 .gitignore 屏蔽,不会进公开仓库。
不配凭据也能跑——本地出图完全够用,上传那步取消勾选就行。
源码在 GitHub
工具已经开源,MIT 协议。
仓库:https://github.com/xsoway/wx_upload_cover_tool
🚀 功能特性
- 🎨 多套内置封面样式:极简 / 深空 / 暖纸 / 霓虹 / 清新,全部基于 HTML/CSS 模板,可自由扩展
- 📐 固定 900×383 横版,符合公众号封面尺寸,导出自动规范化
- 🔤 自适应文字排布:标题 / 副标题自动缩放适配,支持「眉题」拆分(
[标签] 标题语法) - 🌐 Web 前端:实时流式日志,下拉选择标题与模板,勾选是否上传
- 🖥️ 命令行运行:本地一键生成
- 🔁 标题 / 副标题互换:一键突出副标题
- 🔒 凭据安全:微信凭据仅存本地
config/config.ini,已被.gitignore屏蔽
代码结构很收敛,没有把逻辑堆在一个文件里:
├── wx_upload_cover.py # 核心:生成 / 规范化 / 上传
├── web_server.py # Web 后端(流式日志)
├── web.html # Web 前端
├── cover_template_*.html # 五套封面样式模板
├── common/ # logger / config_loader(自包含)
├── docs/preview/ # 五张样式预览图
└── start_web.sh # 一键启动
你可以怎么用
如果你也被公众号封面折腾过,无非两条路。
想直接拿现成的:uv sync --locked 装依赖,playwright install chromium 装内核,跑起来选个你喜欢的样式。
想要自己的风格:照着最小那个模板改 CSS,加一张封面,让整套样式跟你的号一致。
上不上传、用不用 Web 前端,都是可选项——本地纯生成也成立。
#公众号封面 #Playwright #HTML模板 #微信素材 #AI工具 #开源




