用途
Astro Release Images 用于为 astro.build 上的 Astro 次版本或大版本发布博客文章创建并转换发布配图。每次 Astro 发布博客都使用两种图形,在品牌渐变背景上展示大号版本号(如 "7.2"、"6.10"):
| 角色 | 最终文件名 | 格式 | 尺寸 | Frontmatter 字段 |
|---|---|---|---|---|
| 博客封面/主视觉 | blog-post-astro-<version>.webp | WebP | 1500×643 | coverImage |
| 社交/OG 图 | og-astro-<version>.jpg | JPG | 1200×630 | socialImage |
它们存放在 astro.build 仓库的 src/content/blog/_images/astro-<vvv>/ 目录中,目录名去掉小数点(例如 7.2 → astro-720,6.10 → astro-6100)。
图片中的版本号不是可编辑文本,而是被烘焙为单一矢量 <path> 的轮廓字形。本技能使用 Astro 品牌字体("Obviously",字重 475 "Semibold")重新生成该轮廓、自动居中,并拼接回模板,同时保持背景、渐变、投影和颗粒不变。
主要能力
- 使用品牌字体重新生成版本号矢量轮廓
- 自动居中版本号轮廓
- 将新轮廓拼接回品牌模板
- 通过无头 Chrome 以 2× 渲染并降采样,输出最终 WebP/JPG 格式
使用方式
重要:这是一个两阶段流程,不要一次性全部运行。有两个硬性检查点,每个检查点都需停下并等待用户。
- 在生成任何内容之前确认版本号。
- 生成 SVG 后停下,让用户在转换为 webp/jpg 之前目视确认。
不要跳过步骤。光栅转换重做成本低,但绝不应交付用户尚未目视检查的最终资源。
前置条件
本技能 assets/ 中已捆绑:
- og-template.svg、blog-post-template.svg — 品牌模板
- Obviously.woff2 — Astro 品牌字体(字重轴 290–475;图形使用 475)
所需工具/包:
- Python 3 及 fonttools、uharfbuzz、brotli:pip3 install fonttools uharfbuzz brotli
- 无头 Google Chrome(render.sh 用它来清晰渲染渐变、模糊滤镜和混合模式;基于 librsvg 的渲染器可能不够忠实)。如有需要,可通过 CHROME 环境变量覆盖二进制路径。
- cwebp 用于 WebP 输出:brew install webp
- sips(macOS 内置)
阶段 1 — 确认版本
在触碰任何文件之前,确保知道准确的版本字符串。
- 如果用户未提供版本,询问(例如 7.2、6.10、8.0)。
- 按图形中应出现的方式精确书写——包括大版本号是否带尾部 .0(8.0),或两位数次版本号(7.10)。
- 在继续前向用户确认:"我将为 Astro 7.2 生成发布图片——对吗?"
- 版本确认前不要生成 SVG。
阶段 2 — 生成 SVG
每个模板运行一次 scripts/set-version.py。它输出带有新的居中版本号的 SVG。
cd skills/astro-release-images
python3 scripts/set-version.py assets/og-template.svg /tmp/og-<version>.svg <version>
python3 scripts/set-version.py assets/blog-post-template.svg /tmp/blog-post-<version>.svg <version>
7.2 的示例:
python3 scripts/set-version.py assets/og-template.svg /tmp/og-7.2.svg 7.2
python3 scripts/set-version.py assets/blog-post-template.svg /tmp/blog-post-7.2.svg 7.2
脚本会打印字形边界框;检查其是否水平居中(bbox 中心 x 应等于 viewBox 宽度的一半——og 为 600,blog-post 为 750)。
停下——获取用户确认:渲染一个快速预览让用户查看,然后停下并请用户确认图形正确后再转换。不要自行进入阶段 3。
直接展示 SVG,或快速 PNG 预览,例如:
CHROME="${CHROME:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}"
"$CHROME" --headless --disable-gpu --window-size=1200,630 \
--screenshot=/tmp/og-<version>-preview.png "file:///tmp/og-<version>.svg"
等待明确批准(例如 "looks good"、"ship it")。如需修改,调整并重新预览。
阶段 3 — 转换为博客格式
仅在用户批准后执行。scripts/render.sh 使用无头 Chrome 以 2× 渲染、降采样,并根据输出扩展名写入最终格式。
# og / social -> JPG 1200x630
scripts/render.sh /tmp/og-<version>.svg <dir>/og-astro-<version>.jpg 1200 630
# blog cover -> WebP 1500x643
scripts/render.sh /tmp/blog-post-<version>.svg <dir>/blog-post-astro-<version>.webp 1500 643
将它们放入 astro.build 仓库中该发布的图片目录:
src/content/blog/_images/astro-<vvv>/blog-post-astro-<version>.webp
src/content/blog/_images/astro-<vvv>/og-astro-<version>.jpg
其中 <vvv> 是去掉小数点的版本号(7.2 → 720,6.10 → 6100)。
在博客文章 frontmatter 中引用它们:
coverImage: '/src/content/blog/_images/astro-<vvv>/blog-post-astro-<version>.webp'
socialImage: '/src/content/blog/_images/astro-<vvv>/og-astro-<version>.jpg'
适用场景
- 为 Astro 次版本或大版本发布博客文章准备配图
- 需要将版本号嵌入品牌模板并保持视觉一致性的场景
- 需要在生成最终光栅图前进行人工目视确认的发布流程
限制
- 命名在不同版本间有过漂移(短横线、下划线、blog-post-cover、header)。请遵循当前 6.x/7.x 约定:blog-post-astro-<version>.webp + og-astro-<version>.jpg
- astro.build 的 _resolveImage.ts 仅支持以下封面/社交图格式:PNG、JPG/JPEG、WebP。不支持 SVG 或 AVIF。两者都应预先优化(schema 推荐 WebP)。
- 版本文本是轮廓化的,不是真实文本——无法在 SVG 中查找/替换 "7.2";数字只是路径坐标中偶然出现的数字。务必使用 set-version.py 重新生成。
- 字体、字重(475)、比例和基线在 set-version.py 中固定为常量;两个模板共享相同的文本比例,因此相同常量对 og 和 blog-post 均适用。
- HarfBuzz 无法直接读取 .woff2(无 brotli 解压),因此 set-version.py 会在整形前将字体解压为内存中的 sfnt。如果换成原始 .ttf/.otf 字体,这仍然有效。
- 如果 Chrome 不在默认 macOS 路径,运行脚本前设置 CHROME=/path/to/chrome。
- 收费、价格、平台等信息暂未提供。