01|问题的样子
做公众号的人大概都有这个经历:
打开PS或者稿定设计,选模板,改文字,调颜色,导出。一张封面搞定。
耗时 8到15分钟。
如果你一周发 3篇,一年就是 156张封面。每张平均算10分钟,一年花在封面上的时间:26个小时。
26个小时能干什么?够写两篇深度长文了。
但这还不是最让人头疼的。真正的问题是——风格不统一。
今天心情好用蓝色,明天用橙色,后天换个模板又是绿色。读者点进来一看,还以为关注了三个号。
我之前就是这个状态。直到有一天我决定:用代码解决重复劳动。
不过说实话,这个想法不是我凭空想出来的。
我是看了「8点虾聊AI」公众号的文章才动的念头。
他们的排版很舒服——封面有渐变底色、底部有个半透明的提要块、正文里信息卡和互动卡的配色协调一致。我当时一张张截图下来研究,数了数:一篇文章里大概有 4-5种不同类型的图片组件,每种都有自己的位置规则和颜色规范。
我想,如果把这些东西做成模板,以后写文章的时候只换文字不换样式,该多省事。
所以这篇文章,与其说是一份技术分享,不如说是一篇学习笔记。先在这里真诚鸣谢 8点虾聊AI 公众号——本文参考和借鉴了你们的排版风格。如果你们觉得有不妥之处,随时联系我处理。
02|我要什么(先想清楚再动手)
在写第一行代码之前,我先拆解了一张我觉得好看的封面图,列出它包含的所有元素:
上面是内容区:渐变背景打底(900×500px),然后从上往下依次是主标题(42px白色粗体)、副标题(20px浅色)、元信息行、阅读时间带个🕐图标。
中间是提要块:一个半透明白色的圆角卡片,里面放标签流和一句话摘要。这块是我觉得最巧妙的设计——相当于给还没点进来的读者一个"预览"。
下面是署名区:作者名字固定在底部,谁也别挤它。
一共7个元素,每个都有明确的位置规则和样式参数。
我希望最终能做到:
目标明确了,开干。
03|第一次跑通(v1.0)
技术选型很直接:Python + Pillow(PIL)。
为什么不用HTML/CSS画?因为公众号的渲染引擎会干掉大部分CSS属性。font-weight: bold?过滤掉。background: linear-gradient()?Android端直接失效。连 <style> 标签都会被整体移除。
所以只能用最笨也最可靠的方法——用代码画像素。
核心逻辑说白了就三件事:
第一,创建一块画布。900×500像素的空白图像,就像一块空白的画板。
第二,填充渐变背景。从顶部颜色到底部颜色,一行一行地过渡。怎么过渡呢?每一行的RGB值按比例插值计算。比如顶部的蓝是(123,159,232),底部的蓝是(91,126,216),那中间第250行(正中间)的颜色就是这两个值的平均数。
代码写出来大概长这样:
PYTHON
for y in range(500): # 从第0行画到第499行 r = int(r1 + (r2-r1) * y / 500) # 红色通道插值 g = int(g1 + (g1-g1) * y / 500) # 绿色通道插值 b = int(b1 + (b2-b1) * y / 500) # 蓝色通道插值 draw.line([(0,y), (900,y)], fill=(r,g,b)) # 画这一行
对,就是这么暴力——一行一行地画,画500次。
第三,在指定位置写字。标题放在顶部居中,署名固定在底部,剩下的元素按顺序往下排。
第一次跑出来的效果?能用,但丑。纯蓝底白字,什么装饰都没有,像1998年的个人主页。
但重要的是——路通了。从想法到图片,中间只需要运行一条命令。
04|四次迭代,从能用到好用
接下来的一天里,经历了四轮迭代:
这是工作量最大的一步。
我为每套配色定义了 19个色值:封面渐变的起止色2个,各种文字颜色5个,5种卡片的底色,4种分割线颜色,还有描边和其他杂项3个。
6套方案 × 19个色值 = 114个精确配好的颜色。
这些数字不是拍脑袋写的。每套方案的色值都参考了对应领域成熟产品的设计语言:
切换方式呢?改一个字符串:
PYTHON
'scheme': 'sunset' # 改这里,全套跟着变
以前换配色要在PS里调15分钟,现在改两个单词的事。
参考虾聊AI的封面风格,我在底部加了一个半透明提要块——白色45%透明度,圆角12px,里面放标签流和摘要文字。
第一版出来,署名被提要块吃掉了。
原因很简单:画布高度420px,上面塞了标题、副标题、元信息、阅读时间,下面还要塞提要块和署名。空间不够,后面的元素就盖住了当时的画面大概是这个样子的:
CODE
┌──────────────────────┐│ 主标题 ✅ ││ 副标题 ✅ ││ 元信息 ✅ ││ 阅读时间 ✅ ││ ┌─ 提要块 ─┐ ││ │ 标签+摘要 │ │ ← 挤到这里│ └──────────┘ ││ by 深海 ❌被遮挡! │ ← 署名没了└──────────────────────┘
修复过程:
修完之后再跑一遍——署名回来了,提要块也在,大家相安无事。
这次教训就一句话:先算好空间再画,别画完了才发现装不下。
把整套模板从"8点虾聊AI"的风格参数切换到"智行问道"。涉及的东西不多:
这一步验证了一件事:参数化设计的价值。品牌切换只改了字典里的几个默认值,零行逻辑代码需要动。这就好比你盖房子,水电走线都预埋好了,换套家具而已。
用七把尺标准做了自审,得分85分。主要扣分项:封面500px偏高、forest配色对比度略低、缺少输入参数校验。
我的态度是:能用的先上,完美的等下一版。
05|现在它能干什么
当前系统的能力一览:
从"打开PS做10分钟"到"改个标题敲一下回车10秒",后续每篇文章的封面制作成本基本归零。
当然,这个账不能这么算。第一次搭建花了大约6小时,按一年52篇文章来算,节省的时间大概8个多小时——差不多刚好回本。
但真正划算的不是时间账。是另外两件事:
第一,风格一致性有了保证。 不管你今天心情好不好、不管赶稿赶到几点,输出的封面永远是同一套配色体系。读者不会觉得"这号是不是换人了"。
第二,决策成本归零了。 再也不用纠结"今天用什么颜色""这个标题字号多大合适"——这些决策已经在搭建系统的时候一次性做完了。后续只是执行。
06|踩过的坑
Windows系统字体路径不是固定的。我的做法是按优先级依次尝试4个候选字体:微软雅黑粗体 → 微软雅黑常规 → 黑体 → 宋体。
如果用户的机器上一个都没有?那就用PIL内置的默认字体。丑是丑点,但不报错不崩溃。
经验就一条:永远要有降级方案。
这些CSS特性在公众号里不可用:
微信的渲染引擎大概停在2015年的水平。别用它不支持的东西,用了就是给自己埋雷。
114个色值,如果手动在PS里一套一套调,每套15分钟,总共1.5小时。
写成配置字典之后,新增一套配色只需要3分钟——复制一套,改19个十六进制颜色值。
更重要的是:配色一旦确定,所有组件自动继承。不存在"封面换了蓝色但信息卡还是旧橙色"的不一致问题。因为它们读的是同一个字典。
07|适合谁用(也不适合谁)
整个系统的使用流程三步:
Step 1:把脚本复制到你的文章目录Step 2:修改 params 字典(大约20行配置,全是中文注释)Step 3:python _push_template.py,去output文件夹取图
不需要懂前端,不需要装PS,不需要任何设计基础。唯一的前提是安装Python和Pillow(pip install Pillow一行命令)。
但它不是万能的。
擅长的是结构化、重复性高的图片生成——封面、信息卡、二维码引导卡这种"换汤不换药"的东西。
如果你想做复杂的海报、艺术感强的插图、精修的照片——请用专业工具,代码干不了那个。
另外,第一次搭建确实要花时间。我从零到v2.3用了大半天,其中一半时间花在调间距、调颜色、修bug上。只有当你持续产出内容的时候,这个前期投入才划算。
一年发个三五篇的话,直接用稿定设计可能更省心。
这套生成器的代码不到800行,功能说到底就一件事——把重复劳动自动化。
但我觉得真正有价值的不是代码本身,是做这个过程中的几个收获:
逆向解构是最好的学习。 我不是设计师,但我通过一张张截图、一个个元素地拆解别人的作品,理解了"好的排版"背后有哪些规则。这些规则比我写的那几百行代码管用得多。
先完成再完美。 v1.0出来的时候真的很丑,但如果等到"完美"再出手,估计到现在还在调第一个像素。
站在别人肩膀上不丢人。 这篇文章的封面风格来自8点虾聊AI,配色思路参考了各类成熟产品,字体渲染逻辑来自PIL官方文档和社区经验。原创不值钱,能把现有的东西组合好、用起来,才值钱。
最后再说一次:感谢 8点虾聊AI。你们让我看到了什么是好的公众号排版,也希望这篇文章能让更多人知道你们的存在。
本文封面由 Python PIL 自动生成,排版风格借鉴自 8点虾聊AI 公众号。