Bundle
publish-size-check
发布尺寸检查:对照目标平台规格,检查图片能不能发、哪一项参数过不了。零依赖,只查几何参数。
- Source
- Stephen-pc
- License
- MIT
- Updated
- Updated 7 days ago
Readme
# publish-size-check
[](https://github.com/Stephen-pc/publish-size-check/actions/workflows/ci.yml)
[](https://www.python.org/downloads/)
[](#为什么需要它)
[](LICENSE)
> 发布尺寸检查 —— 对照目标平台的几何规格,告诉你这张图**能不能发、是哪一项过不了**。
零依赖(纯标准库,不需要 Pillow)、原件只读、结果确定。
```console
$ python scripts/spec.py --check cover.png --target 小红书
### cover.png
1024×1024px · 0.6MB · 无损
[X] 小红书 / 笔记封面(方版) —— 不能发布
结论: 救不了:像素不足,必须从源文件按更大尺寸重新导出(放大无效)
[X] 宽度 1024px 小于要求 1080px
修法: 重新导出为 ≥1080px 宽(放大现有图片无法恢复清晰度)
```
---
## 为什么需要它
**AI 出图的默认尺寸,基本都过不了主流平台。**
实测三种最常见的 AI 出图尺寸投小红书封面:
| 产出尺寸 | 结果 |
|---|---|
| 1024×1024 | ✗ 宽度差 56px |
| 1024×1536 | ✗ 宽度不足 + 比例不对 |
| 1536×1024 | ✗ 比例完全不对 |
这不是边界情况,是**主流工作流的默认产出**。而平台的报错往往只说"图片不符合要求",不告诉你差多少、差在哪一项。
更隐蔽的一类:**dpi 字段达标,但实际印不出来**。
一张 `800×600 @300dpi` 的图,dpi 元数据完全合格,但按 300dpi 印出来只有 **68mm 宽**,达不到期刊单栏 88mm 的要求。**改 dpi 数字不会增加一个像素**——这类图必须从源文件重新导出。多数工具只比 dpi 数值,会直接放行。
本工具按 `像素数 ÷ dpi × 25.4 = 实际印刷宽度(mm)` 判定,能抓出这一类。
---
## 快速开始
```bash
git clone https://github.com/Stephen-pc/publish-size-check.git
cd publish-size-check
# 一键看效果:跑五种典型场景,自动清理临时文件
python demo.py
# 体检一个文件(指定平台)
python scripts/spec.py --check cover.png --target 小红书
# 先看看某平台到底要什么
python scripts/spec.py --spec 小红书
# 不确定发哪,扫全部社媒平台
python scripts/spec.py --check cover.png
# 多图连发(≥2 个文件会自动追加「整组是否整齐」检查)
python scripts/spec.py --check 1.png 2.png 3.png --target 小红书
# 程序化消费
python scripts/spec.py --check cover.png --target 小红书 --json
# 列出规格库收录的平台
python scripts/spec.py --list
```
需要 Python 3.8+,**不需要安装任何第三方包**。
### 也可以当命令行工具装
```bash
pip install .
publish-size-check --check cover.png --target 小红书
```
装完后规格库会随包一起装好,路径自动定位;也可以用环境变量 `PUBLISH_SIZE_CHECK_SPEC` 指定自己的规格库。
---
## 支持的平台
| 平台 | 槽位 | 可信度 |
|---|---|---|
| 微信公众号 | 头条封面 / 次条封面 / 正文配图 | 已交叉印证 |
| 小红书 | 笔记封面(竖版)/ 笔记封面(方版)/ 笔记内页 | 已交叉印证 |
| 哔哩哔哩 | 视频封面 | 已交叉印证 |
| 知乎 | 回答/想法配图 / 文章封面 | 社区共识 |
| 微博 | 博文配图 / 头条文章头图 | 社区共识 |
| 抖音 | 视频封面(9:16)/ 图文封面(3:4) | 社区共识 |
| 微信视频号 | 视频封面 / 视频画面 | 社区共识 |
| 学术投稿 | 连续色调图 / 线条图 | 社区共识 |
| 印刷交付 | 胶印数码印刷 / 大幅喷绘 | 社区共识 |
| 甲方交付 | 可编辑源文件 | 经验值 |
共 **10 个平台 / 20 个槽位 / 46 个可解析名称**。平台参数支持 id、中文名、别名,模糊匹配也能命中(`红书` → 小红书、`投个稿` → 学术投稿)。
**可信度三级**,写在数据里,不藏:
- `verified` 已交叉印证 —— ≥2 个独立来源,且必须填 `source`(自检强制检查)
- `community` 社区共识 —— 无官方统一口径,存在多种写法
- `experience` 经验值 —— 需复核
---
## 输出长什么样
每条问题分三级(`[X] 错误` / `[!] 警告` / `[i] 提示`),每条带**具体修法**,最后给一句**行动结论**——因为用户真正要的不是问题清单,而是"我现在该干什么":
```
结论: 救不了:尺寸和比例都不对,只能按目标规格重新出图
结论: 救不了:像素不足,必须从源文件按更大尺寸重新导出(放大无效)
结论: 能救:转换格式即可,画质不受影响
```
### 多图连发:指出改哪一张
一次传多张时(小红书最多 18 图、微博九宫格),**单张全达标但整组不整齐**是最常见的翻车方式。本工具会做一次跨文件的组级检查,并且**点出少数派是哪一张**,而不是甩一句"三张都不一致":
```
============================================================
多图一致性检查(共 3 张)
[X] 小红书 —— 不能发布
[X] 尺寸不统一:1242×1660(2张)、1080×1440(1张)
>> 结论: 这一组的主因是 cover3.png 的尺寸和其余不一致……
统一按同一规格重导一遍即可,不用逐张处理。
```
问题清单不值钱,**指出改哪一张才值钱**。
---
## 作为 Agent Skill 使用
本仓库同时是一个可用的 Agent Skill(适配 WorkBuddy / Claude 等支持 `SKILL.md` 的平台)。
```bash
# 安装到用户级 skills 目录
cp -r . ~/.workbuddy-ai/skills/publish-size-check/
```
装好后有两种触发方式:
**① 直接问** —— 用户给了文件并问到发布尺寸:
> 「这图发小红书会不会糊」「平台要多大尺寸」「dpi 够吗」「投稿插图够不够清晰」「被退回来说分辨率不够」
**② 寄生自检(覆盖面最大的用法)** —— 出图流程结束后自动跑,用户不需要知道这个技能存在:
```
用户: 帮我做一张小红书封面
↓
[出图技能] 生成封面文件
↓
★ 有文件落盘 + 用户提到了发布平台 → 自动体检
↓
"封面已生成:1242×1660。顺带确认过小红书规格,可以直接发。"
```
汇报是**分级**的:通过就一句话带过,有问题才展开细节并**给出替代方案**("要我按规格重新出一版吗?")。用户没要求体检时,不会甩一份 30 行诊断打断体验。
`SKILL.md` 里有完整的触发协议、协作边界和扩展指南。
---
## 作为 CodeBuddy / WorkBuddy 插件安装
本仓库同时是一个**插件市场(marketplace)**,可以一条命令装进 CodeBuddy / WorkBuddy:
```bash
# 1. 添加本仓库作为插件市场
/plugin marketplace add Stephen-pc/publish-size-check
# 2. 安装插件
/plugin install publish-check@publish-size-check
# 3. 立即生效,无需重启
/reload-plugins
```
装好后技能即刻可用,触发方式和上面的 Agent Skill 完全一致。
### 与「直接复制 skill」的区别
| | 复制 SKILL.md | 装成插件 |
|---|---|---|
| 升级 | 手动重拷 | `/plugin update publish-check@publish-size-check` |
| 团队分发 | 各自拷贝 | 写进 `.codebuddy/settings.json`,协作者自动获得 |
| 组件命名空间 | 无 | `publish-check:publish-check` |
| 适用场景 | 单人、临时试 | 长期使用、团队统一 |
### 本地开发 / 不联网安装
```bash
/plugin marketplace add ./publish-size-check
/plugin install publish-check@publish-size-check
```
### 仓库结构(双入口)
```
publish-size-check/
├── .codebuddy-plugin/
│ └── marketplace.json # 市场清单:声明本仓库提供哪些插件
├── plugins/
│ └── publish-check/ # 插件包(会被复制进版本化 cache)
│ ├── .codebuddy-plugin/
│ │ └── plugin.json # 插件清单
│ ├── LICENSE
│ └── skills/
│ └── publish-check/ # ← 技能本体,与仓库根目录内容一致
│ ├── SKILL.md
│ ├── demo.py
│ ├── scripts/
│ └── references/
├── SKILL.md # 仓库根目录 = 直接可用的技能形态
├── scripts/
├── references/
└── demo.py
```
根目录保留技能形态,是为了**不装插件的人也能直接 `cp -r` 使用**;`plugins/publish-check/` 是插件形态。两处的技能文件**内容逐字节相同**(CI 会校验),改完记得同步:
```bash
cp SKILL.md demo.py plugins/publish-check/skills/publish-check/
cp scripts/*.py plugins/publish-check/skills/publish-check/scripts/
cp references/platforms.json plugins/publish-check/skills/publish-check/references/
```
### 为什么没有做成完整插件市场里的「原生插件」
插件还能挂 `commands/`、`agents/`、`hooks/`、MCP server。本工具**故意不挂**:
- 不需要 hook —— 寄生自检靠 `SKILL.md` 里的触发协议,装了插件就自动生效,不需要在用户机器上跑钩子。
- 不需要 MCP server —— 那要求常驻进程和 stdio 协议,与「零依赖、跑完就退出」的设计冲突。
- 不需要 command —— 技能本身就能被自然语言触发,多一个斜杠命令只是多一个要维护的入口。
**能少挂一个组件就少挂一个** —— 每挂一个,用户装之前的信任成本就高一档。
---
## 作为 DeepSeek Harness(dsh)插件安装
本仓库同时是一个 **dsh 插件包**,可以直接装进 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness):
```bash
dsh plugin --profile web add github:Stephen-pc/publish-size-check
```
装好后 `publish-check` 会出现在技能目录里,触发方式和上面的 Agent Skill 完全一致。
也可以从 [dsh-market](https://github.com/dsh-market/dsh-market) 一键安装 —— 它内置的插件列表 [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) 收录了本插件。
### 它长什么样
```
publish-size-check/
├── package.json # 声明 dsh.bundle
├── cordis.patch.yml # bundle patch 层:往 profile 树插一条 loader entry
├── lib/index.js # 技能 provider:把 SKILL.md 挂到 ctx.skills
├── tools/dsh-selftest.mjs
└── SKILL.md # ← 与仓库根是同一份
```
`lib/index.js` 是一层**很薄的接线**,不是第二个实现:
- **零依赖** —— 只 import `node:fs/promises` / `node:url` / `node:path`,与 `scripts/spec.py` 只用 Python 标准库是同一个原则。
- **不复制正文** —— 候选和正文都在调用时从 `SKILL.md` 现读,改正文不必动这个文件,也不会出现「描述与正文两份、各自漂移」。
- **不覆盖本地版本** —— 它报 `bundled` 秩(600),你在 `~/.dsh/skills/publish-check` 放的本地特化版(`user-dsh` = 400)仍然优先。
判定逻辑始终只有一份,在 `scripts/spec.py`。
### 一个容易踩的坑:`{skill_base}`
`SKILL.md` 正文里写的是 `python {skill_base}/scripts/spec.py` —— `{skill_base}` 是 CodeBuddy / WorkBuddy 形态的占位符,宿主会在运行时替换它。
**dsh 不认这个占位符。** 它走的是另一套机制:provider 报一个 `resourceBase`,宿主把基准目录写进 `<skill_resources>`,并要求模型「把技能里提到的相对路径解析到基准目录下」。
所以 provider 在 `get()` 时把 `{skill_base}/` 削掉,正文里留下的是 dsh 惯例的裸相对路径(基准目录 = 包根):
```bash
python scripts/spec.py --check cover.png
```
不这么做的话,模型会拿到一条执行不了的命令。削成相对路径、而不是替换成绝对路径,是因为 Windows 绝对路径带反斜杠,写进代码块后在 bash 里会被当成转义字符。
### 自检
```bash
node tools/dsh-selftest.mjs
```
用一个假 `ctx` 走完 `apply()` → `list()` → `get()`,并验证正文引用的相对路径真的落在包根下。CI 还会 `npm pack` 解压后**按安装形态再跑一遍** —— 抓的是 `files` 字段漏文件这类只有用户才会撞上的错。
想更彻底一点,可以拉起官方运行时真的加载一次(需要联网装依赖,不进 CI):
```bash
cd /tmp && npm init -y
npm install @deepseek-ai/cordis@~4.0.4 @deepseek-ai/dsh-skill@0.2.0-rc.2 \
@deepseek-ai/dsh-llm@0.2.0-rc.2 @deepseek-ai/dsh-scope@0.2.0-rc.2
node <本仓库>/tools/dsh-real-load.mjs <本仓库>
```
它会走 `ctx.skills.get()` → `renderSkillContent()`,把**模型最终收到的那段文本**打出来——包括上面那条基准目录说明。
---
## 这个工具**不**做什么(重要)
**只查几何参数。不查内容合规。**
| 查 | 不查 |
|---|---|
| 像素尺寸、宽高比 | ❌ 内容是否违规 |
| dpi、实际印刷宽度 | ❌ 是否含二维码/联系方式(平台限流项) |
| 文件体积、格式 | ❌ 文字占画面比例 |
| 色彩模式要求 | ❌ 字体版权、图片版权、商标 |
| 多图尺寸一致性 | ❌ 医疗/金融等特殊行业资质标识 |
**不查的那些不是不重要,是本工具做不到。** 范围窄是刻意的——正因如此才能做到零依赖、结果确定、不误判内容。
其它边界:
- **原件只读**。永不修改、移动、重命名、删除任何输入文件。只诊断,不代改。
- **不给有害建议**。绝不说"把 640px 的图缩到 200px"——尺寸不足只能重做,放大无法恢复清晰度。
- **不猜图类型**。判断不了的事(如投稿图是照片还是线条图)会让你选,而不是并列报一堆矛盾结论。
- **不猜规格**。规格库没有的平台用通用兜底值,并**明确标注这是兜底、不是该平台的真实要求**。
---
## 维护规格库
平台会改版。规格库带时效字段,**超过 180 天需复核**:
```bash
python scripts/spec.py --validate
# [i] 规格库核验于 2026-10-12,0 天前,在有效期内
```
### 改完一定要跑自检和测试
```bash
python scripts/spec.py --validate # 抓 schema / 别名冲突 / 数值不自洽,有错退出码 1
python scripts/test_spec.py # 46 项回归测试
```
`--validate` 会检查:schema 缺失、confidence 非法、**verified 却没填 source**、别名冲突、aspect 与 canvas 不自洽、`tolerance`/`alt` 用法错误、安全区不完整、体积类型错。**退出码 1,可以直接接 CI。**
### 加一个平台
在 `references/platforms.json` 的 `platforms` 数组里加一项:
```json
{
"id": "your-platform",
"name": "平台名",
"aliases": ["别名1", "别名2"],
"kind": "social_cn",
"confidence": "community",
"source": "来源链接或说明",
"slots": [
{
"slot": "cover",
"label": "封面",
"canvas": { "w": 1080, "h": 1440 },
"aspect": "3:4",
"max_bytes": 20971520,
"formats": ["jpg", "png"],
"safe_area_pct": { "top": 6, "bottom": 12, "left": 6, "right": 6 }
}
]
}
```
`canvas` 支持三种写法:
- `{ "w": 1080, "h": 1440 }` —— 精确值
- `{ "w": 1146, "h": 717, "tolerance": "gte" }` —— 不小于(B 站封面就是这类)
- `{ "w": 1242, "h": 1660, "alt": [{ "w": 1242, "h": 1656 }] }` —— 多备选取值
### 发现规格有分歧时怎么办
**不要挑一个值写死。** 用 `alt` 记录多个取值,在 `notes` 里说明分歧——真实世界的规格分歧本身就是有价值的信息。抖音的 9:16 / 3:4 就是典型(取决于上传入口)。
### 一条纪律
**运营经验帖不能当规则写。** 网上大量"据说某平台……"的说法没有任何官方或第二方来源。写进规格库前,请确认至少有一个可追溯的来源;拿不准就标 `experience` 并在 `notes` 里写清楚,不要冒充权威。
---
## 测试
```bash
python scripts/test_spec.py
```
**46 项回归测试,纯标准库,不依赖 pytest。** 自建临时图片、跑完自动清理,退出码 0 / 1 可接 CI。
覆盖:规格库自检、图片头解析(PNG/JPEG/GIF/TIFF)、dpi 与物理宽度、`gte` 与 `alt` 语义、单点裁决、行动结论、多图一致性、JSON 契约、别名冲突检测。
---
## License
MIT
Install
dsh plugin --profile web add github:Stephen-pc/publish-size-check
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install publish-size-check from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.