文章封面批量生成:一条命令产出 1200×675 专属封面(PIL 实战)
文章封面批量生成一条命令产出 1200×675 专属封面PIL 实战写技术博客的人大多经历过这一刻文章发了列表页却挂着一张灰蒙蒙的默认图。点率差一截还以为是自己标题起得不好。这篇文章做一件事用一条命令给每篇文章生成一张 1200×675 的专属封面并且讲清楚封面到底有没有挂上——不是我以为传上去了而是用可验证的判据确认。全部代码基于真实工作流PIL 12.3.0 实测无虚构。一、先立判据封面挂没挂谁说了算在动手之前必须先定义成功。我踩过的坑是上传接口返回 200、编辑器里也显示了图但文章详情页的分享缩略图还是默认图。后来固定用两个判据互相印证文章页og:image抓详情页 HTML读meta propertyog:image content...。是平台默认图形如.../202112131616291007.png就是没挂上是i-blog.csdnimg.cn/direct/*.png这种带direct路径的才是真封面。列表页/详情页首图视觉确认个别平台 og 更新有延迟截图看一眼最稳妥。经验接口成功和用户能看到是两件事。凡是要交付到用户眼前的结果都要有一个用户视角的验收动作。这条以后端开发也一样适用。二、尺寸与规格为什么是 1200×675用途建议尺寸说明CSDN 文章封面1200×67516:9列表卡片不变形通用 OG 图1200×630社交分享裁剪安全区知乎/公众号头图900×383 / 1080×432更宽的横条本文以 1200×675 为主。原则只有一条按平台推荐尺寸的整数倍做避免二次缩放发虚。三、生成器设计每篇文章一张专属图专属的意思是只看封面就知道是哪篇。做法是三要素——主色按文章主题分配 标题文字 关键词标签。# gen_cover.py —— 一条命令生成一张封面# 用法: python gen_cover.py 输出.png 标题 标签1 标签2 [主色]importsys,hashlibfromPILimportImage,ImageDraw,ImageFont W,H1200,675# 主题色板深底 高对比前景暗色模式下也稳PALETTE[((24,32,56),(96,165,250)),# 深蓝 / 亮蓝((28,40,38),(52,211,153)),# 深绿 / 薄荷((42,28,46),(244,114,182)),# 深紫 / 粉((46,34,24),(251,191,96)),# 深棕 / 琥珀((30,36,48),(148,163,184)),# 石板灰 / 银]defpick_palette(seed_text):同一篇文章每次生成同一配色——可复现改内容才会改色idxint(hashlib.md5(seed_text.encode(utf-8)).hexdigest(),16)%len(PALETTE)returnPALETTE[idx]defload_font(size,boldFalse):candidates[C:/Windows/Fonts/msyhbd.ttcifboldelseC:/Windows/Fonts/msyh.ttc,C:/Windows/Fonts/simhei.ttf,C:/Windows/Fonts/Arial.ttf,]forpathincandidates:try:returnImageFont.truetype(path,size)exceptOSError:continuereturnImageFont.load_default()defwrap_text(draw,text,font,max_w):按像素宽度折行中文无空格也能断lines,cur[],forchintext:trialcurchifdraw.textlength(trial,fontfont)max_w:curtrialelse:ifcur:lines.append(cur)curchifcur:lines.append(cur)returnlinesdefmain():outsys.argv[1]titlesys.argv[2]tagssys.argv[3:]bg,fgpick_palette(title)imgImage.new(RGB,(W,H),bg)dImageDraw.Draw(img)# 左上角色带 右下角弱化圆制造层次又不抢字d.rectangle([0,0,W,10],fillfg)forr,alphain((150,26),(110,20),(70,14)):d.ellipse([W-r,H-r,Wr,Hr],fillfg)# 标题自动缩放 折行最多三行forsizein(72,64,56,48):fload_font(size,boldTrue)lineswrap_text(d,title,f,W-160)iflen(lines)3:breaky150forlninlines[:3]:d.text((80,y),ln,fontf,fill(245,247,250))yint(size*1.45)# 标签小胶囊排在标题下方x80ftload_font(30)fortgintags[:3]:twd.textlength(tg,fontft)pad18d.rounded_rectangle([x,y30,xtwpad*2,y3052],radius26,outlinefg,width3)d.text((xpad,y41),tg,fontft,fillfg)xtwpad*220# 右下角落款弱化处理fsload_font(24)d.text((W-260,H-56),技术实战笔记,fontfs,fill(150,158,172))img.save(out,PNG)print(fOK{out}{W}x{H})if__name____main__:main()跑一条python gen_cover.py cs-cover-484.png\Chrome 自动化「点了没反应」\ChromeCDP自动化几个设计取舍都是被现实毒打出来的配色用标题做哈希种子同一篇文章每次生成同一张图改一次标题才变色。批次重跑不会出现昨天蓝今天绿方便对照。标题自动缩放 按像素折行中文没有空格按字符数折行必然溢出或参差。textlength按实际字宽判断长标题自动缩到 48px。暗色底 亮前景CSDN 有深色模式白底封面在深色列表里像一块膏药。圆角胶囊用outline不用填充填充色一多就花描边干净。四、批量化一次给 N 篇文章出封面文章多了就该有个清单。用 JSON 驱动一条命令全出# batch_cover.py —— 读 cover-list.json批量生成 输出缺失报告importjson,subprocess,sys,os LISTcover-list.json# [{id:167589876,title:...,tags:[a,b],file:cs-cover-876.png}]defmain():itemsjson.load(open(LIST,encodingutf-8))missing[]foritinitems:ifos.path.exists(it[file]):print(fSKIP{it[file]}已存在)continuecmd[sys.executable,gen_cover.py,it[file],it[title],*it.get(tags,[])]subprocess.run(cmd,checkTrue)missing.append(it[file])print(fDONE 新生成{len(missing)}张清单共{len(items)}篇)if__name____main__:main()再配一个核查脚本把上面说的判据落成代码——这才是交付的闭环# check_cover.py —— 逐篇读 og:image报出没挂封面的文章importre,sys,urllib.request DEFAULT_HINT202112131616291007# 平台默认图特征串defcheck(article_id):urlfhttps://blog.csdn.net/qq_58833970/article/details/{article_id}requrllib.request.Request(url,headers{User-Agent:Mozilla/5.0})htmlurllib.request.urlopen(req,timeout15).read().decode(utf-8,ignore)mre.search(rmeta propertyog:image content([^]),html)ogm.group(1)ifmelsestatusMISSINGifDEFAULT_HINTinogornotogelseOKprint(f{article_id}{status}{og[:80]})if__name____main__:foraidinsys.argv[1:]:try:check(aid)exceptExceptionase:print(f{aid}ERROR{e})踩坑提醒curl 直抓文章页经常被拦空响应/验证页。稳妥做法是走浏览器CDP 连上已登录的 ChromeRuntime.evaluate读document.querySelector(meta[propertyog:image]).content。需要登录态的页面别用裸 HTTP 客户端赌运气。五、上传封面的最后一公里图生成了怎么塞进发布流程才是真门槛。以 CSDN 为例要点三条封面 input 是隐藏的input.el-upload__input用DOM.setFileInputFiles直接塞文件路径比模拟点击文件选择对话框可靠一万倍。裁剪弹窗的确认按钮文案是「确认上传」而且它不一定是button标签——用*全标签遍历按文本匹配别限定button,div,span。新建文章发布时塞文件会弹裁剪框已发布文章回编辑页补封面时塞文件不弹框。两条路径都要留代码。// 片段塞文件 点「确认上传」全标签遍历awaitsend(DOM.setFileInputFiles,{nodeId:inputNodeId,files:[pngPath],});// 轮询等裁剪弹窗出现再全标签找「确认上传」constrawaitev((function(){ var els document.querySelectorAll(*); for (var i 0; i els.length; i) { var t (els[i].innerText || ).trim(); if (t 确认上传) { els[i].click(); return clicked; } } return not-yet; })());改已发布文章会触发平台风控一天内第二次保存要微信扫码。所以补封面这种活儿能批量就批量能提前就提前——每改一次就要扫一次码码还有 10 分钟寿命人等码、码等人两头空耗。六、一条命令的完整形态最终固化下来的日常用法# 1) 有新增文章就往 cover-list.json 里加一条# 2) 一条命令批量生成 上传 核查python batch_cover.pynodecs-cover-batch.jscs-cover-batch.js负责连 CDP → 逐篇打开发布页 → 塞图 → 确认 → 保存 →当场回读 og:image 复核最后打印一张OK/MISSING对照表。哪篇 MISSING一眼看到不用逐篇翻网页。七、这套做法的复用价值回头看封面这件事真正的产出不是 5 张 png而是三个可迁移的习惯先定验收判据再动手og:image是不是默认图比我觉得传上去了可靠。可复现生成哈希定色 JSON 清单任何时候能重出一模一样的图。批处理 自核查生成、上传、验收串成一条命令报告直接告诉你哪几篇没挂上。下次平台改版、上传路径变了要改的只有cs-cover-batch.js一个文件清单和生成器原样复用。把手工重复关进脚本是这类琐事唯一的解法。本文方法来自真实的多平台发布工作流PIL 12.3.0 / 1200×675 / 五篇 CSDN 文章封面全部核验挂载。所有代码可直接运行。

相关新闻

一张 RTX 3060 12GB 跑三元 27B + 128K 上下文——NInfer Fusion KVMem 实测

一张 RTX 3060 12GB 跑三元 27B + 128K 上下文——NInfer Fusion KVMem 实测

一、项目说明本项目意图在低成本平台上;运行开源框架Qwen3.8 27B的开源模型,本项目的可行性来源于B站大佬推出的NInfer引擎以及得益于三元量化模型的极低权重;并且保留了全精度原模型百分之九十八的能力(B站UP口径)。在…

2026/10/14 3:34:37 阅读更多 →
安装nature-skills

安装nature-skills

从https://github.com/Yuan1z0825/nature-skills 克隆并安装nature-skill 来源:[https://github.com/Yuan1z0825/nature-skills](https://github.com/Yuan1z0825/nature-skills)(第三方开源、Apache-2.0 协议)网络:你的网络直连 …

2026/10/14 3:34:37 阅读更多 →
算法岗实习面试全攻略:从简历到Offer的实战复盘

算法岗实习面试全攻略:从简历到Offer的实战复盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 3:34:37 阅读更多 →

最新新闻

Dropout 正则化原理与实战:从过拟合到泛化能力提升

Dropout 正则化原理与实战:从过拟合到泛化能力提升

1. 为什么一个"随手关掉神经元"的操作能成为深度学习的基石第一次在代码里写下nn.Dropout(p0.5)的时候,我其实没太当回事——不就是训练时随机扔掉一半神经元嘛,听起来像个正则化的小把戏。直到有一次复现一篇图像分类论文,模型在训…

2026/10/14 4:24:51 阅读更多 →
从60到150 t/s:Strata推理栈与INT4量化在48G显存上的实战调优

从60到150 t/s:Strata推理栈与INT4量化在48G显存上的实战调优

1. 先说说那三秒:149.7 t/s 砸到眼前那天晚上我蹲在测试机前面,盯着终端里不断滚动的数字,一时没回过神来。屏幕上清清楚楚写着“149.7 t/s”。按标题里的说法,就是那套组合——内部代号 Strata 的推理栈,加上一个叫 q…

2026/10/14 4:24:51 阅读更多 →
Java毕设实战:基于爬虫的题库自动生成系统完整解析

Java毕设实战:基于爬虫的题库自动生成系统完整解析

简介:毕设项目-利用爬虫的题库自动生成系统 是面向计算机相关专业本科生毕业设计场景的完整工程,适用于需要快速搭建可运行题管理平台的Java开发者。针对题库建设中题目来源单一、手工录入效率低等问题,整体以Java为后端核心、Vue为管理端页面…

2026/10/14 4:24:51 阅读更多 →
机械原理课程设计洗瓶机:凸轮机构实现推头匀速回程三倍速

机械原理课程设计洗瓶机:凸轮机构实现推头匀速回程三倍速

简介:基于机械原理的洗瓶机课程设计资料面向机械专业本科生,完整呈现从功能分解、运动方案设计到执行机构选型的全过程,适合完成课程设计或复习机构学知识时参考。内容围绕瓶子推进、旋转与刷洗三大动作展开,明确了推进距离600mm、…

2026/10/14 4:24:51 阅读更多 →
旅游线路查询接口分页漂移导致数据抓取错位的排查与规避

旅游线路查询接口分页漂移导致数据抓取错位的排查与规避

1. 一个看似普通的查询需求,怎么就翻车了事情是这样的,前阵子帮一个做旅游内容聚合的朋友看他们后台的数据对账问题。他们有一个模块是抓取某旅游线路平台(就是那种典型的“黑马旅游网”风格的线路查询站点)的线路数据&#xff0c…

2026/10/14 4:24:51 阅读更多 →
西门子RPC开发实战:从通信接口到产线落地的完整路径

西门子RPC开发实战:从通信接口到产线落地的完整路径

简介:这份西门子RPC开发功能文档面向工业自动化领域的开发者、设备集成工程师与数控系统调试人员,聚焦SINUMERIK 840D/840Di/810D平台下远程过程调用的接口规范与开发方法。文档系统梳理了主机接口、PLC/NCK接口、HMI与NCK/PLC的OEM交互接口等核心模块&a…

2026/10/14 4:23:50 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →