本地博客图片自动上传工作流:Cloudflare R2 + PicList + Codex 实战教程

本地博客图片自动上传工作流:Cloudflare R2 + PicList + Codex 实战教程
从本地 Markdown 到 CSDN用 Cloudflare R2 PicList Codex 自动发布博客图片写博客时图片一多最耗时的往往不是写内容而是把本地图片一张张上传到 CSDN、掘金、知乎或微信公众号编辑器再逐个替换图片链接。这套工作流把这件事自动化本地 Markdown 本地图片 ↓ Codex 调用发布脚本 ↓ PicList 将图片上传至 Cloudflare R2 ↓ 脚本把本地图片路径替换为公开 HTTPS 链接 ↓ 生成可直接导入 CSDN 等平台的 Markdown最终你只需要在本地正常写文章、正常插图发布前运行一次命令或让 Codex 执行任务就能得到一份图片链接已经替换完成的发布版 Markdown。一、这套方案解决什么问题以 CSDN 为例直接导入带本地图片的 Markdown 时常见问题包括图片仍然是本地路径导入后无法显示文章里有几十张图片需要逐张上传操作重复且容易漏图片文件名含中文、空格或特殊字符上传或生成链接时容易出现乱码图床链接不稳定平台转存或外链加载失败多篇文章共用一个图片目录后期难以定位图片属于哪篇文章。这套方案的目标不是“换一个图床”而是把写作、图片托管、图片链接替换、平台导入串成一条稳定的发布流水线。二、三个工具各自负责什么1. Cloudflare R2保存图片文件Cloudflare R2 是对象存储服务。它负责保存文章图片并提供可公开访问的图片地址。在这套工作流中R2 相当于“图片仓库”R2 Bucket └── articles/ ├── ai-product-manager-roadmap/ │ ├── image-001.png │ └── image-002.png └── codex-workflow/ ├── image-001.png └── image-002.png建议每篇文章使用独立目录后期查找、迁移或删除图片都会更清楚。2. PicList把本地图片上传到 R2PicList 是本地图片上传客户端。它可以通过 Amazon S3 兼容协议连接 Cloudflare R2并提供本地上传接口。在这套工作流中PicList 负责接收脚本传来的本地图片上传图片到 R2返回图片的公开 URL可按配置对图片进行压缩、转换 WebP、命名和归档。3. Codex 发布脚本批量处理 MarkdownCodex 不需要手动逐张上传图片。它调用发布脚本后脚本会自动读取本地 Markdown 文件找出 Markdown 图片语法和 HTML 图片标签中的本地图片跳过本来就是远程链接、data:图片、代码块示例和占位符将真实存在的本地图片交给 PicList 上传把原文中的本地路径替换成 R2 的公开 HTTPS 地址生成一份可导入博客平台的 Markdown输出图片映射表和发布报告方便核查。三、首次配置Cloudflare R2这一部分只需配置一次。完成后Cloudflare R2 会作为文章图片的长期存储位置PicList 负责把本地图片上传到这里。3.1 进入 R2 对象存储登录 Cloudflare Dashboard。为了后续操作更直观可以先在右上角将控制台切换为中文。在左侧菜单进入存储和数据库 → R2 对象存储首次使用 R2 时Cloudflare 可能会要求先开通 R2 订阅或补充支付方式。这一步是为了启用对象存储服务具体可用额度、计费规则以 Cloudflare 当前控制台展示为准。3.2 创建图片 Bucket点击创建存储桶新建一个专门用于博客图片的 Bucket。Bucket 名称建议使用简洁、稳定的英文例如blog-assets blog-images my-blog-images建议一个博客或一个个人知识库可先使用一个 Bucket图片目录由后续的 PicList 或发布脚本统一管理例如articles/文章-slug/Bucket 名称创建后尽量不要频繁修改否则 PicList 配置也需要同步更新。3.3 创建供 PicList 使用的 API Token进入刚创建的 Bucket在R2 概览页 → 管理中选择Create API Token。权限选择Object Read Write作用范围建议仅限定到刚刚创建的博客图片 Bucket而不要开放给所有 Bucket。确认后创建 Token。创建成功后Cloudflare 会显示三项后续配置 PicList 必须使用的信息Access Key ID Secret Access Key Endpoint URL请立即安全保存这三项信息尤其是Secret Access Key它通常只显示一次关闭页面后无法再次查看原值。不要把密钥写入 Markdown、Git 仓库、截图或公开文章。3.4 配置图片公开访问地址PicList 需要用Endpoint URL将图片上传到 R2但 Markdown、浏览器和 CSDN 需要的是可以直接访问图片的公开 URL。两者不是同一个地址。你需要在 Bucket 的公开访问设置中启用 R2 的公开开发域名或绑定自己的自定义域名。准备好一个公开图片前缀例如https://pub-xxxx.r2.dev或https://img.example.com三类地址的作用如下地址类型示例用途R2 Endpoint URLhttps://account_id.r2.cloudflarestorage.comPicList 上传到 R2 时填写R2 公开开发域名https://pub-xxxx.r2.dev文章图片外链、测试访问自定义域名https://img.example.com文章图片外链、长期品牌化使用不要将 Cloudflare 控制台地址或 Endpoint URL 当成文章图片链接。发布前务必在无登录状态的浏览器中测试一张已上传图片能否直接打开。四、PicList 连接 Cloudflare R24.1 安装并进入图床设置从 PicList GitHub Releases 下载并安装客户端。打开 PicList 后进入图床设置。Cloudflare R2 兼容 Amazon S3 协议因此图床类型请选择Amazon S34.2 填写 R2 连接参数将第 3 部分保存的 R2 信息填入 PicList。不同 PicList 版本的字段名称可能略有差异但填写逻辑一致PicList 字段应填写的内容说明Access Key IDR2 的Access Key ID创建 API Token 后得到Secret Access KeyR2 的Secret Access Key请勿泄露或上传到仓库Bucket你的 Bucket 名称例如blog-assetsEndpointR2 的Endpoint URL格式通常为https://account_id.r2.cloudflarestorage.comRegion按 PicList 页面提示填写R2 常见填写方式为auto以当前客户端校验为准Custom URL / Public URLR2 公开开发域名或自定义域名例如https://pub-xxxx.r2.dev不要填 Endpoint其中最容易填错的是Custom URL / Public URL这里必须是浏览器、CSDN、掘金等平台能够直接访问图片的地址而不是 R2 的上传终结点。4.3 设置存储路径与文件命名建议使用规则化的远程路径避免所有图片堆在 Bucket 根目录。常见配置如下{year}/{month}/{md5}这样可以按年月归档并通过md5避免文件重名。对于本文介绍的 Codex 发布工作流也可以让脚本在每次发布时临时把上传目录设为articles/文章-slug/例如articles/cloudflare-r2-piclist-codex-guide/这样同一篇文章的所有图片会集中存放便于以后迁移、清理或定位。4.4 设为默认图床并验证上传配置完成后点击确认/保存将该配置设为默认图床在 PicList 中随便上传一张测试图片复制返回链接在浏览器无登录状态下打开能正常显示才说明“R2 上传 公开访问”链路已经完成。若上传成功但浏览器打不开图片优先检查Custom URL / Public URL是否误填成了 Endpoint URLR2 是否已开启公开访问或已正确绑定自定义域名Bucket 名称、Endpoint、密钥是否属于同一个 Cloudflare 账户和同一个 R2 配置图片路径模板是否导致公开 URL 拼接异常。4.5 开启 PicList 内置 Server后续的发布脚本需要调用 PicList 的本地上传接口因此请保持 PicList 打开并开启它的内置 Server。常见上传接口为http://127.0.0.1:36677/upload若你为 PicList Server 配置了 API Key接口可能是http://127.0.0.1:36677/upload?keyYOUR_KEY端口以 PicList 实际配置为准。完成这一步后Codex 或脚本才能把 Markdown 中的本地图片批量交给 PicList 上传。五、文章文件应该如何组织建议一篇文章使用一个独立文件夹将 Markdown 和图片放在一起my-blog/ └── codex-image-publish-workflow/ ├── article.md ├── images/ │ ├── workflow.png │ ├── piclist-config.png │ └── result.png └── cover.png文章中使用相对路径引用图片![整体工作流](images/workflow.png) ![PicList 配置示例](images/piclist-config.png) img srccover.png alt封面图不建议一开始就在 Markdown 中手动填写 R2 URL。保留本地相对路径能够让文章在本地编辑、预览和迁移时更方便发布脚本会在生成发布版文件时自动替换它们。六、安装并使用 Markdown Platform Publisher Skill工作流Github链接https://github.com/STRUGGLE1999/markdown-platform-publisher-skill/tree/main这套工作流依赖一个用于“本地图片上传 Markdown 链接替换”的 Skill 或脚本。它的核心能力是支持![alt](image.png)支持img srcimage.png跳过已经是https://、data:或协议相对地址的远程图片跳过代码块中的示例图片语法上传前将图片暂存为 ASCII 文件名降低中文文件名、空格和特殊字符造成的 URL 编码问题按文章创建独立的远程图片目录输出发布版 Markdown、图片映射表和发布报告可选校验图片公开链接是否真的可以访问。假设你的项目中已经包含脚本scripts/publish_markdown_piclist.py常用命令如下。6.1 让 Codex 帮你安装这个 Skill完成前面第三、四章节的Cloudflare R2 配置和PicList 连接 Cloudflare R2 配置后就可以让 Codex 帮你安装图片自动发布 Skill。直接把下面的 GitHub 链接发给 Codex让它帮你安装markdown-platform-publisher-skill可以直接对 Codex 说text 请帮我安装这个 GitHub 仓库中的 markdown-platform-publisher Skill https://github.com/STRUGGLE1999/markdown-platform-publisher-skill/tree/main整个 Cloudflare R2 和 PicList 的配置过程只需要做一次第一次会花一些时间。后续写完带有本地图片的 Markdown 博客后直接把 Markdown 文件发给 Codex即可自动上传图片、替换本地图片链接并生成可导入 CSDN 等博客平台的 Markdown 文档。在使用前需要确认两项信息PicList 本地上传接口端口Cloudflare R2 最终公开图片域名。1. 确认 PicList 本地上传接口端口PicList 默认的本地图片上传接口通常是http://127.0.0.1:36677/upload其中36677是 PicList 内置 Server 的默认端口。使用前请打开 PicList 并确认已经开启内置 Server。如果没有修改过端口一般直接使用默认地址即可http://127.0.0.1:36677/upload如果你曾修改过 PicList 的 Server 端口则需要将上面的36677替换为实际端口号。2. 获取 R2 最终公开图片域名Codex 需要知道图片上传后的最终公开访问域名才能将 Markdown 中的本地图片路径替换为可直接访问的 HTTPS 图片链接。在 Cloudflare 控制台中按下面路径查看进入存储和数据库 → R2 对象存储点击你创建的 Bucket例如blog-assets打开顶部的设置Settings找到Public Development URL公共开发 URL确认已经启用页面中会显示一条Public Bucket URL / 公共存储桶 URL。它通常长这样https://pub-xxxxxxxxxxxxxxxx.r2.dev这条地址就是 R2 的最终公开图片域名也是 PicList 中需要填写的Custom URL / 公网访问域名。例如图片上传到 R2 后的路径为articles/codex/01-codex.png那么最终公开访问地址就是https://pub-xxxxxxxxxxxxxxxx.r2.dev/articles/codex/01-codex.png注意不要填错成下面这个地址https://account_id.r2.cloudflarestorage.com这个是S3 Endpoint URL用于 PicList 连接 Cloudflare R2 并上传图片不是给 Markdown、CSDN 或浏览器直接展示图片使用的公开域名。简单区分如下地址类型示例用途S3 Endpoint URLhttps://account_id.r2.cloudflarestorage.comPicList 连接 R2、上传图片R2 公网访问域名https://pub-xxxxxxxxxxxxxxxx.r2.devMarkdown 图片展示、浏览器访问、CSDN 导入Cloudflare 将r2.dev地址称为Public Development URL。启用后可以在 Bucket 的Settings页面中查看对应的Public Bucket URL。6.2 基础发布命令如果你不想通过CodeX也可以自己在命令行运行下面命令Windows PowerShell 示例python scripts\publish_markdown_piclist.py --inputD:\my-blog\codex-image-publish-workflow\article.md--expected-url-prefixhttps://pub-xxxx.r2.dev--check-links --keep-stagedmacOS / Linux 示例python scripts/publish_markdown_piclist.py\--input/Users/your-name/my-blog/codex-image-publish-workflow/article.md\--expected-url-prefixhttps://pub-xxxx.r2.dev\--check-links\--keep-staged运行完成后通常会生成articlePicList发布版.md articlePicList发布版.image-map.json articlePicList发布版.publish-report.json articlePicList发布版.piclist-staged/其中文件或目录用途articlePicList发布版.md最终可直接导入 CSDN、掘金、知乎等平台的文章.image-map.json本地图片路径与远程图片 URL 的映射关系.publish-report.json本次发布的统计、校验和异常信息.piclist-staged/上传前生成的 ASCII 文件名暂存图片便于排查文件名问题6.3 指定文章远程目录默认情况下脚本可根据 Markdown 文件名自动生成英文 slug远程目录类似articles/codex-image-publish-workflow/也可以自行指定python scripts\publish_markdown_piclist.py --inputD:\my-blog\codex-image-publish-workflow\article.md--slugcodex-image-publish-workflow--expected-url-prefixhttps://pub-xxxx.r2.dev--check-links建议slug使用全小写英文、数字和短横线例如ai-product-manager-learning-roadmap cloudflare-r2-piclist-guide codex-markdown-publisher这样生成的图片地址更干净也更适合长期维护。七、直接让 Codex 执行发布任务配置完成后日常不必记住完整命令。打开包含文章的项目后可以直接对 Codex 说把当前 article.md 转成可导入 CSDN 的 Markdown。 请使用 PicList 本地上传接口上传所有本地图片到 Cloudflare R2 将图片路径替换为公开 HTTPS 链接 图片目录使用 articles/codex-image-publish-workflow/ 并检查生成后的图片链接是否能访问。也可以把关键参数写得更明确请执行 Markdown 发布工作流 - 输入文件D:\my-blog\codex-image-publish-workflow\article.md - PicList 上传接口http://127.0.0.1:36677/upload - R2 公开域名https://pub-xxxx.r2.dev - 远程目录articles/codex-image-publish-workflow/ - 要求上传所有本地图片、替换 Markdown 和 HTML 图片路径、校验公开链接、 输出发布版 Markdown、图片映射 JSON 和发布报告。Codex 执行后重点查看以下结果original_local_image_refs rewritten_remote_refs remaining_local_image_refs理想情况是{original_local_image_refs:12,rewritten_remote_refs:12,remaining_local_image_refs:0}这意味着文章原本有 12 个本地图片引用已全部替换为远程链接没有遗漏本地路径。八、发布到 CSDN 等平台的操作脚本成功后使用生成的发布版文件而不是原始 Markdown 文件。推荐流程打开articlePicList发布版.md随机抽查几张图片链接确认浏览器中可打开在 CSDN 新建文章选择导入 Markdown导入发布版.md文件检查封面图、长图、表格附近图片和 HTML 图片是否显示正常保存草稿并预览确认无误后发布。同一份发布版 Markdown 通常也适合导入掘金知乎博客园语雀Obsidian Publish支持 Markdown 导入的微信公众号编辑器或第三方编辑器。不同平台对 HTML、图片懒加载属性或外链策略可能略有差异。对于重要文章建议先导入草稿并预览一次。九、完整日常工作流完成首次配置后每次写文章可以按以下方式操作1. 在本地写 Markdown图片继续用相对路径插入 2. 完成文章后确认 PicList 已打开且内置 Server 已启动 3. 让 Codex 执行发布工作流或运行发布脚本 4. 查看发布报告确认 remaining_local_image_refs 0 5. 打开发布版 Markdown抽查图片链接 6. 将发布版 Markdown 导入 CSDN 等平台 7. 原始 Markdown 保留在本地发布版用于外部平台这样可以把“逐张上传图片、复制链接、反复替换”的重复操作压缩成一次批处理。十、常见问题排查1. 脚本提示无法连接 PicList检查PicList 是否已经打开PicList 内置 Server 是否已开启接口端口是否为36677你的接口是否设置了 API Key本地防火墙是否阻止了该端口。2. PicList 能上传但生成的图片在浏览器打不开优先检查R2 是否已配置公开访问PicList 的 Public URL / Custom URL 是否填写为真正可公开访问的图片域名是否误把 R2 Endpoint URL 当成图片公开地址上传路径和公开域名拼接后的地址是否正确。3. 图片上传后 URL 出现乱码或平台导入失败常见原因是原图文件名含有中文、空格或特殊字符。建议本地图片尽量使用英文、数字、短横线和下划线命名保留脚本的 ASCII 暂存文件功能不要手动修改脚本生成的远程 URL对文件名异常的图片先在本地重命名后重新执行发布。4. 有些图片没有被替换检查 Markdown 中是否使用了非常规写法例如![](./images/a.png title)或复杂的 HTML 属性、变量占位符、模板语法。先查看.publish-report.json和.image-map.json确认脚本识别到哪些图片。必要时把特殊图片写法改成标准形式![图片说明](images/a.png)5. 图片链接已经是远程地址为什么没有重新上传这是正常行为。发布脚本通常会跳过https://... http://... data:... //example.com/...因为这些本来就不是本地文件。若你希望把旧图床迁移到 R2需要使用专门的“远程图片下载并重新上传”流程而不是普通的本地图片发布流程。6. 为什么要保留原始 Markdown原始 Markdown 中保留相对路径适合继续在本地编辑、Obsidian 预览或迁移项目。发布版 Markdown 中是公开 URL适合导入 CSDN 等外部平台。建议两份都保留article.md # 原始写作版 articlePicList发布版.md # 对外发布版十一、结语Cloudflare R2、PicList 和 Codex 组合后真正节省时间的并不是“上传一张图片”而是把整篇文章的图片发布过程变成可重复执行的自动化流程。以后写博客时只需要专注于内容和本地排版写文章 → 插本地图片 → 运行发布工作流 → 导入平台当一篇文章有十几张、几十张甚至上百张图片时这种批量上传、自动替换链接、自动校验的方式能明显减少重复劳动也能让多平台发布更稳定、更可维护。