Cursor实战案例-图形图像-44-海报设计代码化:利用Pillow在图片指定区域动态叠加高精文字与透明阴影底栏|TaoToken 统一 Key 调用图像处理脚本
1. 海报批量生成里文字模糊和底栏不透明到底卡在哪做电商运营或者量化周报的朋友大概率都遇到过这个场景手里有一张设计好的背景图需要把每天变动的数据、标题、活动文案批量叠加上去生成几十上百张分享卡片。听起来是个很简单的需求但真动手写脚本的时候问题一个接一个冒出来。最典型的就是文字模糊。很多人第一反应是用 OpenCV 的putText直接往上写结果发现英文字母边缘全是锯齿中文压根写不出来——因为putText只支持 Hershey 点阵字体根本不认 TTF 文件。就算勉强用上了字号一大边缘的毛刺感在手机屏幕上特别明显跟设计稿的质感差了十万八千里。第二个坑是底栏不透明。为了让文字在复杂背景上能看清通常会在文字下面垫一条深色底栏。但如果直接用纯色矩形整张图会显得很生硬像贴了块膏药。想要那种半透明、带点渐变过渡的“磨砂玻璃”效果用 OpenCV 得手动分离 RGB 通道再算加权公式代码又长又难调。第三个坑是文字换行。中英文混排的时候半角和全角字符宽度不一样如果按固定字数切分排出来的文字参差不齐长的溢出背景短的又留一大片空白。这个问题的本质是你得按像素宽度来算而不是按字符个数来算。这篇内容就是围绕这三个痛点来的。我会用 Cursor 配合 Pillow 写一套可复用的海报合成脚本核心解决三件事按像素宽度自动折行、RGBA 半透明渐变底栏、8 方向偏移描边加投影。最后再通过 TaoToken 的统一 Key 把脚本接进去实现多图批处理调用。适合谁看做自动化运营、需要批量出图、又不想依赖设计软件手动改的开发者。2. 用 TaoToken 统一 Key 接管脚本调用省掉多平台配置的麻烦在正式写 Pillow 代码之前先把调用链路理清楚。我们这套脚本最终是要跑批处理的可能今天处理 50 张明天处理 200 张。如果每次都要手动改脚本里的参数、或者在不同平台之间来回切换 Key效率会非常低。TaoToken 在这里的角色是一个统一的模型调用入口。你可以把它理解成一个“总开关”不管底层用的是哪个模型、哪个服务对外都只暴露一个 Base URL 和一个 API Key。对于我们的海报脚本来说这意味着可以把“生成文案”和“合成图片”两个环节串起来——先用统一 Key 调模型生成每天的标题和正文再把返回的文本喂给 Pillow 脚本出图。具体来说TaoToken 的 API 地址是https://taotoken.net/api官网入口在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。你需要在控制台里创建一个 API Key这个 Key 就是后面所有请求的凭证。这里有个细节要注意TaoToken 兼容 OpenAI 风格的接口格式所以你在代码里配置的时候base_url填https://taotoken.net/apiapi_key填你申请到的那个字符串模型 ID 按你实际要用的填。这三件套Base URL Key Model ID是后面所有调用的基础缺一不可。为什么不用直连某个单一平台因为批量出图这个场景里文案生成和图像处理是两条线。文案可能今天用这个模型、明天换那个模型如果每个都单独配 Key、单独改代码维护成本太高。统一 Key 的好处就是换模型的时候只改一个 Model ID 参数其他都不用动。另外如果你后面要把这套脚本做成定时任务或者接到 CI 流程里统一 Key 也方便做权限管理和用量统计。控制台里能看到每个 Key 的调用情况排查问题的时候有据可查。3. 可复制的 Pillow 绘制配置字体、锚点、RGBA 底栏一次配好这一节是核心直接上可复制的配置和代码。整个脚本我拆成三个部分底栏渐变叠加、文字自动折行、高精度描边绘制。你可以把下面的代码存成poster_engine.py后面直接 import 用。先看依赖。在虚拟环境里装这两个pip install Pillow10.0.1 pydantic2.3.0Linux 环境下如果渲染 TTF 报错先补一个系统库sudo apt-get install libfreetype6-dev然后是核心配置。我习惯把字体路径、颜色、尺寸这些抽成一个 JSON 配置方便批量任务里动态替换。存成poster_config.json{ font_path: /System/Library/Fonts/PingFang.ttc, font_size: 24, line_spacing: 1.3, text_color: [255, 255, 255, 255], stroke_color: [12, 18, 24, 255], stroke_width: 2, shadow_offset: 3, shadow_alpha: 100, overlay: { x: 50, y: 700, w: 700, h: 220, start_alpha: 200, end_alpha: 20, fill_rgb: [18, 24, 38] } }注意font_path这里写的是 macOS 的苹方字体路径。Windows 下换成C:\\Windows\\Fonts\\msyh.ttcLinux 下换成/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf或者你项目里自带的思源黑体。千万不要硬编码一个不存在的路径否则 Pillow 会直接抛OSError: cannot open resource。接下来是引擎类。核心逻辑我写在下面关键位置加了注释# -*- coding: utf-8 -*- from PIL import Image, ImageDraw, ImageFont import os import logging logging.basicConfig(levellogging.INFO, format%(asctime)s - [%(levelname)s] - %(message)s) logger logging.getLogger(poster_engine) class PosterGenerator: def __init__(self, background_path: str): if not os.path.exists(background_path): raise FileNotFoundError(f未找到背景底图: {background_path}) self.bg_img Image.open(background_path).convert(RGBA) self.width, self.height self.bg_img.size logger.info(f底图加载成功尺寸: {self.width}x{self.height}) def _auto_wrap_text(self, text: str, font: ImageFont.FreeTypeFont, max_width: int) - list: lines [] current_line for char in list(text): test_line current_line char bbox font.getbbox(test_line) line_width bbox[2] - bbox[0] if line_width max_width: current_line test_line else: if current_line: lines.append(current_line) current_line char if current_line: lines.append(current_line) return lines def add_gradient_overlay(self, x, y, w, h, start_alpha180, end_alpha0, fill_rgb(18, 24, 38)): overlay Image.new(RGBA, self.bg_img.size, (0, 0, 0, 0)) draw ImageDraw.Draw(overlay) for offset in range(h): current_y y offset alpha int(start_alpha - ((start_alpha - end_alpha) * (offset / h))) draw.rectangle( [x, current_y, x w, current_y 1], fill(fill_rgb[0], fill_rgb[1], fill_rgb[2], alpha) ) self.bg_img Image.alpha_composite(self.bg_img, overlay) logger.info(f渐变底栏叠加完成Y{y}, 高度{h}px) def draw_high_fidelity_text(self, text, x, y, font_path, font_size, max_width, text_color(255, 255, 255, 255), stroke_color(0, 0, 0, 255), stroke_width2, line_spacing1.3, shadow_offset3, shadow_alpha100): if not os.path.exists(font_path): raise FileNotFoundError(f未找到字体文件: {font_path}) font ImageFont.truetype(font_path, font_size) wrapped_lines self._auto_wrap_text(text, font, max_width) draw ImageDraw.Draw(self.bg_img) current_y y sample_bbox font.getbbox(高) line_height int((sample_bbox[3] - sample_bbox[1]) * line_spacing) for line in wrapped_lines: draw.text((x shadow_offset, current_y shadow_offset), line, fill(0, 0, 0, shadow_alpha), fontfont) if stroke_width 0: for dx in range(-stroke_width, stroke_width 1): for dy in range(-stroke_width, stroke_width 1): if dx ! 0 or dy ! 0: draw.text((x dx, current_y dy), line, fillstroke_color, fontfont) draw.text((x, current_y), line, filltext_color, fontfont) current_y line_height total_height current_y - y logger.info(f文字绘制完成共 {len(wrapped_lines)} 行占用高度 {total_height}px) return total_height def save_poster(self, output_path: str, quality: int 95): final_jpg Image.new(RGB, self.bg_img.size, (255, 255, 255)) final_jpg.paste(self.bg_img, maskself.bg_img.split()[3]) final_jpg.save(output_path, JPEG, qualityquality) logger.info(f海报已导出: {output_path})几个关键点解释一下。_auto_wrap_text里用的是font.getbbox()来算像素宽度而不是len()。这是解决中英文混排参差不齐的核心——每个字符的物理宽度不一样必须按像素算。add_gradient_overlay里逐行画 1 像素高的矩形每行透明度线性递减这样出来的底栏是渐变的不是一块死板的纯色。描边部分用了 8 方向偏移比 Pillow 自带的stroke_width参数效果更细腻尤其是在高亮背景上。4. 跑一遍验证检查文字边缘锐度和底栏透明度代码写完了得实际跑一遍看效果。我写一个测试脚本先生成一张模拟背景图再调用引擎出图。# -*- coding: utf-8 -*- from poster_engine import PosterGenerator from PIL import Image, ImageDraw import os def create_mock_background(path: str): img Image.new(RGB, (800, 1000), color(135, 206, 250)) draw ImageDraw.Draw(img) draw.ellipse([200, 300, 700, 700], fill(255, 255, 255)) img.save(path) def get_system_font(): candidates [ /System/Library/Fonts/PingFang.ttc, C:\\Windows\\Fonts\\msyh.ttc, /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf, ] for p in candidates: if os.path.exists(p): return p raise FileNotFoundError(未检测到系统字体请手动指定 TTF 路径) def main(): mock_bg mock_bg.png output share_poster.jpg create_mock_background(mock_bg) try: font_path get_system_font() gen PosterGenerator(mock_bg) gen.add_gradient_overlay(x50, y700, w700, h220, start_alpha200, end_alpha20) text 【量化策略】今日成交汇报大盘主力资金在券商板块持续净流入策略触发加仓信号当前累计净值 1.352Sharpe 比例 1.68风险处于安全水位。 gen.draw_high_fidelity_text( texttext, x80, y720, font_pathfont_path, font_size24, max_width640, text_color(255, 255, 255, 255), stroke_color(12, 18, 24, 255), stroke_width2 ) gen.save_poster(output) finally: if os.path.exists(mock_bg): os.remove(mock_bg) if __name__ __main__: main()运行之后控制台会输出类似这样的日志2026-06-22 13:30:00 - [INFO] - 底图加载成功尺寸: 800x1000 2026-06-22 13:30:00 - [INFO] - 渐变底栏叠加完成Y700, 高度220px 2026-06-22 13:30:00 - [INFO] - 文字绘制完成共 4 行占用高度 130px 2026-06-22 13:30:01 - [INFO] - 海报已导出: share_poster.jpg打开生成的share_poster.jpg重点检查两个地方。第一文字边缘。放大到 200% 看白色文字外围有一圈深色描边边缘是平滑的没有锯齿感。第二底栏透明度。底栏从下往上透明度逐渐降低顶部几乎透明底部是深蓝黑色过渡自然不会像纯色块那样突兀。如果文字刚好压在背景的白色椭圆上因为有描边和投影依然能看清。这就是 8 方向偏移描边的作用——它相当于给文字加了一圈“保护色”不管背景是亮是暗文字都能保持可读性。验证通过之后就可以把这段逻辑接到 TaoToken 的调用链里了。用统一 Key 调模型生成文案把返回的文本传给draw_high_fidelity_text再批量循环处理多张背景图。整个流程跑通之后每天出几十张海报就是几秒钟的事。5. 常见报错排查401、字体乱码、底栏不透明怎么修实际跑的时候大概率会遇到下面几个报错。我按出现频率排一下对照着改就行。报错一OSError: cannot open resource这个是最常见的原因就一个font_path指向的文件不存在。Pillow 加载字体的时候不会帮你做路径模糊匹配写错了就直接抛。解决办法是把字体文件放到项目目录里用相对路径加载比如resources/fonts/SourceHanSans.ttf。这样不管换到哪台机器只要项目目录结构不变就不会出问题。另外注意 Windows 下路径要用双反斜杠或者正斜杠单反斜杠会被当成转义字符。报错二401 Unauthorized或local proxy failed如果你在调用 TaoToken 接口的时候看到 401先检查三件套Base URL 是不是https://taotoken.net/apiAPI Key 有没有复制完整前后不要有空格Model ID 是不是控制台里实际可用的。local proxy failed通常是本地网络配置的问题检查一下系统代理设置确保请求能正常发出去。这两个报错在接入文档里都有对照说明遇到的时候直接查文档比瞎试快。报错三文字渲染出来是方块或者问号这是字体不含中文字模导致的。DejaVuSans、Arial 这些英文字体里没有汉字FreeType 找不到对应的字形就会渲染成“豆腐块”。解决办法是统一换成支持中文的字体推荐思源黑体或者阿里巴巴普惠体这两个都是免费商用的直接打包进项目就行。报错四底栏看起来还是纯色没有渐变检查add_gradient_overlay里的start_alpha和end_alpha是不是设成了同一个值。如果两个值相等透明度就不会变化出来就是纯色。另外确认一下h参数是不是太小高度太小的话渐变区间短肉眼不容易看出来。一般底栏高度在 150px 以上渐变效果会比较明显。报错五reading choices相关错误这个通常出现在解析模型返回结果的时候。如果你用统一 Key 调模型生成文案返回的 JSON 结构里choices字段是空的或者格式不对就会报这个。检查一下请求参数里的model和messages是不是符合接口要求另外确认返回内容有没有被截断。排查的时候有个小技巧先把stroke_width设成 0把底栏start_alpha和end_alpha设成一样的值跑一遍看基础文字能不能正常显示。基础没问题了再逐步加上描边和渐变这样能快速定位是哪一层出的问题。6. 把脚本接进 TaoToken批量出图就三步整套流程跑通之后批量处理其实就三步准备背景图列表、调模型生成文案、循环调用合成引擎。先申请 API Key入口在控制台的 API Keys 页面。拿到 Key 之后用统一入口调模型生成每天的文案import requests API_BASE https://taotoken.net/api API_KEY 你的_API_Key def generate_copy(prompt: str, model_id: str 你的模型ID): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json } payload { model: model_id, messages: [{role: user, content: prompt}] } resp requests.post(f{API_BASE}/v1/chat/completions, headersheaders, jsonpayload, timeout30) resp.raise_for_status() return resp.json()[choices][0][message][content]拿到文案之后循环处理背景图import glob for bg_path in glob.glob(backgrounds/*.png): copy_text generate_copy(生成一条 80 字以内的今日策略播报) gen PosterGenerator(bg_path) gen.add_gradient_overlay(x50, y700, w700, h220, start_alpha200, end_alpha20) gen.draw_high_fidelity_text( textcopy_text, x80, y720, font_pathresources/fonts/SourceHanSans.ttf, font_size24, max_width640 ) output_name foutput/{os.path.basename(bg_path).replace(.png, .jpg)} gen.save_poster(output_name)如果你后面要做成长期跑的定时任务或者接进 Agent 流程里可以考虑用 Coding Plan 来管理调用配额和模型切换。模型对话入口适合先验证文案生成的效果确认没问题了再批量跑。最后说一个实测下来的经验字体对象不要在循环里反复加载。ImageFont.truetype()每次调用都会读磁盘几百张图跑下来光加载字体就能占掉不少时间。把 Font 对象在循环外面初始化好传进去复用速度会快很多。这个坑我踩过改完之后批处理时间直接砍了一半。

相关新闻

Spring Security AccessDeniedException排查:从异常到权限配置的完整指南

Spring Security AccessDeniedException排查:从异常到权限配置的完整指南

1. 先搞明白:AccessDeniedException到底是谁在什么时候抛出来的1.1 那个“不允许访问”的提示,到底是从哪来的看到org.springframework.security.access.AccessDeniedException这个异常,第一反应应该是:你的项目已经成功进入了 Sp…

2026/10/10 22:56:34 阅读更多 →
SpringBoot+Vue全栈实战:癌症患者交流平台从数据库到部署完整拆解

SpringBoot+Vue全栈实战:癌症患者交流平台从数据库到部署完整拆解

没有任何一个项目,能像“SpringBoot Vue”这样,在前后端分离的学习路线里占据如此稳固的生态位。你随便打开一个招聘网站的后端岗位,要求栏里大概率写着SpringBoot;去翻学生们的毕业设计选题,十个里有六七个都是这套组…

2026/10/10 22:56:34 阅读更多 →
斐波那契数列与黄金分割:蓝桥杯真题精度陷阱与阈值截断解法

斐波那契数列与黄金分割:蓝桥杯真题精度陷阱与阈值截断解法

第一眼看到题目名《Fibonacci数列与黄金分割》,我还以为是让手算黄金分割比,读完题会发现事情没有这么简单。这道蓝桥杯2019年第十届省赛真题的题面很短:输入一个整数n,输出斐波那契数列第n项与第n1项的比值F(n)/F(n1)&#xff0c…

2026/10/10 22:56:34 阅读更多 →

最新新闻

在 Turborepo 与 Yarn Berry 中开发 Next.js 应用:with-berry 示例 Web 应用实战指南

在 Turborepo 与 Yarn Berry 中开发 Next.js 应用:with-berry 示例 Web 应用实战指南

构建工具开发工具CLI 【免费下载链接】turbo Build system optimized for JavaScript and TypeScript, written in Rust 项目地址: https://gitcode.com/gh_mirrors/tu/turbo 点击查看 免费下载 本篇指南以 Turborepo 仓库中 with-berry 示例的 apps/web 应用 READ…

2026/10/10 23:30:04 阅读更多 →
Serverless 冷启动 + Orleans 虚拟 Actor:Agent Substrate 的架构血统考

Serverless 冷启动 + Orleans 虚拟 Actor:Agent Substrate 的架构血统考

Serverless 冷启动 Orleans 虚拟 Actor:Agent Substrate 的架构血统考 【免费下载链接】substrate Agent Substrate: the core system 项目地址: https://gitcode.com/GitHub_Trending/substrate7/substrate 一个看似矛盾的事实正在改写云原生的资源模型&am…

2026/10/10 23:30:04 阅读更多 →
300 轮长会话实测:哪些内容会被 fast-jev-compaction 的「二元删除决策」误伤?

300 轮长会话实测:哪些内容会被 fast-jev-compaction 的「二元删除决策」误伤?

300 轮长会话实测:哪些内容会被 fast-jev-compaction 的「二元删除决策」误伤? 【免费下载链接】fast-jev-compaction Claude Code plugin that replaces the compaction summary with Jev decisions: every tool call and result is scored in one fast…

2026/10/10 23:30:04 阅读更多 →
FireRedTTS3架构剖析:Qwen3 LLM + DiT流匹配如何实现patch级扩散自回归TTS

FireRedTTS3架构剖析:Qwen3 LLM + DiT流匹配如何实现patch级扩散自回归TTS

【免费下载链接】FireRedTTS3 FireRedTTS3: Multilingual and Multi-Dialect Voice Cloning with Instruction-Guided Voice Design and Speech Editing 项目地址: https://gitcode.com/gh_mirrors/fi/FireRedTTS3 点击查看 免费下载 FireRedTTS3 是一个统一的多语…

2026/10/10 23:30:04 阅读更多 →
Selenium自动化测试:抽奖系统概率、库存与UI回归实战

Selenium自动化测试:抽奖系统概率、库存与UI回归实战

抽奖系统的测试,最让人心里没底的从来不是某个按钮能不能点,而是那些肉眼看不透的规则到底有没有在线上环境按预期跑。“中奖概率偏差了零点几”、“库存多扣了一次”、“连续快速点击会不会发出两条抽奖请求”,这类问题在演示环境里靠手工点…

2026/10/10 23:30:04 阅读更多 →
BFO-XGBoost超参数优化:Matlab实现与避坑指南

BFO-XGBoost超参数优化:Matlab实现与避坑指南

简介:本资源面向计算机、电子信息工程、数学等专业的大学生及算法初学者,提供一套基于鳑鲏鱼优化算法(BFO)优化XGBoost的分类预测完整方案,可用于课程设计、期末大作业或毕业设计。压缩包共18个文件,约53.6…

2026/10/10 23:29:04 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/10 11:14: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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →