PicList + R2 + Sink:图床、短链、相册一条龙

前言

图床工具这个品类,说起来挺尴尬的。市面上选择一大堆,PicGo、uPic、iPic、Typora 自带的图片上传功能…… 但真正用起来,总有那么一两个需求满足不了。

我个人用 Cloudflare R2 做图床后端,看重的是免费额度大(10GB 存储 + 每月 1000 万次读操作)而且没有流量费。问题来了,大多数图床工具对 R2 的支持要么没有,要么藏在「自定义 S3」里面配起来很折腾。另一个痛点是短链接,R2 的原始 URL 又臭又长,每次贴图还得手动套一层短链服务,割裂感很强。

PicList 是 PicGo 的一个 fork,但说实话它现在已经比原版好用太多了。它把「R2 S3 直传 + 上传后自动生成短链接 + 相册管理」这三个需求串在了一条线里,不用再开三个工具来回切。这篇就记录一下完整的配置过程。

准备工作

开始之前,先确保下面这些东西已经就绪。

Cloudflare 账号和 R2 存储桶

去 Cloudflare 控制台,左侧菜单找到 R2,创建一个存储桶。桶名随意,本文用 blog-all

创建完桶之后,顺手给它绑定一个自定义域名。R2 默认的 *.r2.dev 域名虽然能用,但那个子域名长得跟乱码似的,而且自定义域名方便以后迁移。我的域名是 s3.marxchou.com,绑定过程就是在 Cloudflare 的 DNS 里加一条 CNAME 指向桶的 R2 终端节点。

Sink 短链服务

Sink 是一个开源的短链接服务,支持 Cloudflare Pages / Workers 一键部署。我这里假设你已经在 Cloudflare Pages 上跑着一个 Sink 实例,域名比如 sink-488.pages.dev

如果还没部署,建议直接去 Sink 的 GitHub 仓库 按文档走一遍,十分钟能搞定。

安装 PicList

macOS 下用 Homebrew 一行搞定:

Terminal window
brew install piclist --cask

装完之后先别急着打开,配置还没写,开了也是白开。

配置 R2 直传

PicList 通过 aws-s3-plist 这个上传器来对接 R2,因为 R2 支持 S3 兼容 API,所以走的是 S3 那套协议。

获取 R2 S3 兼容凭据

进 Cloudflare 控制台 → R2 → 管理 R2 API 令牌 → 创建 API 令牌。

权限选 Object Read & Write,范围限定到你刚创建的桶。创建完把 Access Key ID 和 Secret Access Key 复制下来,这俩只显示一次,丢了大不了重新创建。

同时记下你的 Account ID,在 R2 总览页面能找到,是一串 32 位的 hex。

编辑 data.json

PicList 的配置文件在:

~/Library/Application Support/piclist/data.json

打开 data.json,找到 uploader 这个顶级字段。如果你的 uploader 下面还没有 aws-s3-plist,手动加上。下面是完整的配置项:

"aws-s3-plist": {
"defaultId": "r2-default",
"configList": [
{
"_configName": "Cloudflare R2",
"_id": "r2-default",
"accessKeyID": "<你的 Access Key ID>",
"secretAccessKey": "<你的 Secret Access Key>",
"bucket": "blog-all",
"endpoint": "https://<Account ID>.r2.cloudflarestorage.com",
"url": "https://s3.marxchou.com",
"path": "{year}/{month}/{md5}.{extName}",
"region": "auto",
"forcePathStyle": true,
"acl": "",
6 collapsed lines
"uploadPath": "",
"options": "",
"customDomain": false
}
]
}

关键字段说明:

字段说明
endpointR2 的 S3 API 端点,格式固定:https://<AccountID>.r2.cloudflarestorage.com
url公网访问域名。填你绑定到桶上的自定义域名,返回的图片链接会用这个域名
region固定 "auto",R2 不需要指定区域
forcePathStyle固定 true,R2 走 path-style 寻址
acl留空。R2 在 Cloudflare 控制台配桶级别的公开访问,不走传统 S3 ACL
path上传后的目录结构。{year}/{month}/{md5}.{extName} 表示按年月分目录、文件名为 MD5

切换默认图床

配完 uploader 之后,把 picBed 里的当前图床切过去:

"picBed": {
"current": "aws-s3-plist",
"uploader": "aws-s3-plist",
"aws-s3-plist": {
"_configName": "Cloudflare R2",
"_id": "r2-default"
}
}

保存文件,启动 PicList。拖一张图进去,看看上传区是不是显示了 aws-s3-plist,上传成功后在浏览器里打开返回的链接,能正常显示就没问题。

接入 Sink 短链接

R2 直传搞定了,但返回的链接长这样:

https://s3.marxchou.com/2026/05/a1b2c3d4e5f6...png

每次贴图还得手动去 Sink 后台转短链,麻烦。PicList 内置了 Sink 短链接支持,上传后自动返回短链。

获取 Sink API Token

Sink 的 Token 就是它的登录密码。在 Sink 管理后台 → Settings → API Token 能看到。如果没有 Token 字段,说明你的 Sink 版本稍旧,直接用仪表盘的登录密码就行。

配置短链

data.jsonsettings 块里加上这几行:

"settings": {
"useShortUrl": true,
"shortUrlServer": "sink",
"sinkDomain": "https://sink-488.pages.dev",
"sinkToken": "<你的 Sink API Token>"
}

三个字段缺一不可:

字段说明
useShortUrl必须设为 true,否则不会触发短链服务
shortUrlServer固定 "sink",指定用 Sink 作为短链提供方
sinkDomain你的 Sink 部署域名,结尾不带斜杠
sinkTokenSink 的 API Token / 登录密码

验证

保存 data.json,重启 PicList,上传一张测试图。看上传记录里的链接,应该已经是短链格式了:

https://sink-488.pages.dev/aBcDeF

这时再去 Sink 管理后台,Links 列表里应该也能看到这条新记录。

几个实用功能

配完核心链路之后,PicList 还有几个顺手的功能值得提一嘴。

内置压缩和格式转换

PicList 上传前可以对图片做处理,在 uploader 的每个 config 里加 formatConvertObj

"formatConvertObj": {
"type": "webp",
"quality": 80,
"maxWidth": 1920
}

PNG 截图动不动好几 M,转成 WebP 之后体积直接砍到原来的三分之一甚至更少,对博客加载速度帮助很大。

Typora / Obsidian 联动

在 Typora 的「图像」设置里,把上传服务选为「PicGo (PicList)」,路径填 PicList 的监听端口(默认 36677)。截图后右键上传,图片自动进 R2 并返回短链。

Obsidian 配合 Image Auto Upload 插件也能实现类似效果,粘贴图片即上传。

粘贴格式选择

PicList 上传完图片后自动把链接写进剪贴板,格式可以在设置里选:URL、Markdown、HTML、BBCode 等。个人最常用的是 Markdown 格式,因为博客文章里直接 ![]() 就行。

总结

PicList 最打动我的不是某个单一功能,而是它把「上传 → 短链 → 管理」这条链路上的摩擦降到了最低。以前我上传一张博客配图,要先拖到某个图床工具上传,拿到原始链接,再打开 Sink 后台或 Alfred 快捷指令生成短链,最后手动拼成 Markdown —— 每一步都有操作成本。

现在一条龙搞定,上传即短链,剪贴板即 Markdown。

当然也不是完美的。PicList 的界面跟原版 PicGo 一样 Electron 味十足,启动不算快。但考虑到它解决的实际问题,这些都不算事。

如果你的图床正好是 Cloudflare R2 或任何 S3 兼容存储,又在用 Sink 做短链,PicList 基本是目前最好的选择。