- 开发工具
- 前端
【免费下载链接】picx
🏞️ 一款基于 GitHub API 开发的图床工具,提供图片上传托管和生成图片链接。
PicX 是一款完全基于 GitHub API 开发的开源图床工具,面向需要"图片上传托管 + 生成图片链接"的开发者和博客作者,提供在线使用、无需安装的 Web 服务形态。读完本文,你将掌握 PicX 的核心使用流程(OAuth 授权 / Token 登录、图床配置、多级目录管理)、上传与链接生成的工作原理(GitHub Git Database API 调用链、链接规则模板替换),以及图片压缩、水印、GitHub Pages 部署、PWA 离线化等进阶能力的底层实现。
一、PicX 是什么
PicX 的定位在 README.md 中一句话概括:一款基于 GitHub API 开发的图床工具,提供图片上传托管和生成图片链接。它不依赖任何自建后端服务,而是直接以浏览器为客户端,通过 GitHub REST API 把图片写入用户自己的 GitHub 仓库,再利用 GitHub、GitHub Pages、jsDelivr 等公开资源域名生成可访问的图片链接。
核心亮点
- 在线使用、无需下载、无需安装:项目本身是一个纯前端应用(Vue 3 + Vite),部署在静态托管平台即可使用;
- 操作简单、文档完善、持续维护:提供官方文档、快速开始教程与完善的设置项;
- 代码开源、数据安全、完全免费:源码以 AGPL-3.0 协议开源(见 LICENSE),图片数据存放在用户自己的 GitHub 仓库中,不经过第三方中转服务器。
从仓库 package.json 可以看到,项目使用 pnpm 管理依赖(packageManager: pnpm@11.18.0),核心依赖包括vue@3.5、vue-router、pinia(状态管理)、element-plus(UI 组件库)、axios(HTTP 客户端)以及@jsquash/*系列浏览器端图片编解码库,运行环境要求 Node.js>=24 <25。
二、登录方式:GitHub OAuth 授权与 Token 填写
PicX 提供两种登录方式:
- GitHub OAuth 授权登录:通过 GitHub App 授权,换取可用于调用 API 的访问令牌;
- 填写 GitHub Token 登录:用户手动粘贴自己创建的 Personal Access Token(PAT),跳过 OAuth 流程。
无论哪种方式,最终都要得到一个有效 token 才能调用 GitHub API。底层实现上,所有请求都由 src/utils/request/axios.ts 中创建的 axios 实例统一发出:请求拦截器从本地存储读取用户配置(getLocal(LS_CONFIG)),当命中 GitHub API baseURL 且存在 token 时,自动向请求头注入Authorization: Bearer <token>。相关基础地址与超时配置在 src/common/constant/request.ts:AXIOS_BASE_URL = 'https://api.github.com',AXIOS_TIMEOUT = 300000(5 分钟,考虑到大图上传耗时)。
OAuth 授权状态(token、installationId、授权时间等)由 Vuex 模块 src/stores/modules/github-authorize/index.ts 管理并持久化到 LocalStorage。同时,src/common/constant/settings.ts 定义了GITHUB_AUTHORIZE_EXPIRE = 5 * 24 * 60 * 60 * 1000,即 GitHub App 授权 Token 的有效期为5 天,过期后需要重新授权。
登录后调用getGitHubUserInfo(见 src/common/api/user.ts)获取用户信息,用于展示头像、用户名,并作为图床仓库的 owner。
三、图床配置:仓库、分支与多级目录
登录后需要完成图床配置,核心配置项在 src/common/model/user-config.ts 的UserConfigInfoModel中定义:
| 配置项 | 说明 |
|---|---|
owner/repo | 图床仓库的属主与仓库名 |
branch | 图片写入的目标分支(默认值为master,见 src/common/constant/init.ts 的INIT_REPO_BARNCH) |
email/name | 提交 commit 时使用的 committer 信息 |
dirMode | 目录模式:rootDir(根目录)/dateDir(日期目录)/repoDir(仓库目录)/newDir(新建目录) |
dirList | 仓库内的目录列表(供级联选择) |
仓库的创建与初始化
- 若还没有图床仓库,PicX 可调用
createRepo(src/common/api/repo.ts)直接创建公开仓库,默认仓库名为picx-images-hosting(INIT_REPO_NAME,见 src/common/constant/init.ts); - 由于GitHub Git Database API 不支持在完全空的仓库上操作,
initRepoREADME会先向仓库写入一个README.md文件完成仓库初始化(提交信息为Init repo via PicX),这是源码注释中明确说明的工程细节。
多级目录管理
getDirInfoList与getRepoPathContent(src/common/api/dir.ts)通过 Contents API(GET /repos/{owner}/{repo}/contents/{path},带ref=branch参数)拉取指定路径下的目录与图片,前端以级联组件(repo-dir-cascader)呈现多级目录。限制方面,src/common/constant/settings.ts 定义了NEW_DIR_COUNT_MAX = 5,即新建目录最多支持 5 级层级。
管理页的"上传时间"并非存储字段,而是通过getLatestCommitTime查询该文件路径最近一次 commit 的 author 时间获得(GET /repos/{owner}/{repo}/commits?path=...&per_page=1),这也是图床管理页能按时间排序的底层依据。
四、图片上传:四种选择方式与两条 API 链路
PicX 支持拖拽、复制粘贴、选择文件三种方式选择图片(README 中列为已实现功能),文件进入上传队列后统一走后续处理。
文件类型与大小限制
src/utils/file-utils.ts 中的isImage判定 png / jpg / jpeg / gif / webp / awebp / avif / svg / ico 等格式,isVideo仅支持MP4;IMG_UPLOAD_MAX_SIZE = 30(MB)与VIDEO_UPLOAD_MAX_SIZE = 30(MB)是上传大小上限(src/common/constant/settings.ts)。gettingFilesHandle负责把File通过FileReader转成 base64,并校验类型与大小。
上传前处理:压缩与水印优先
UploadImageModel(src/common/model/image.ts)同时保存originalBase64、watermarkBase64、compressBase64三份数据。真正上传时,src/utils/upload-utils.ts 按压缩结果 → 水印结果 → 原始数据的优先级取 base64 内容:
const tempBase64 = ( img.base64.compressBase64 || img.base64.watermarkBase64 || img.base64.originalBase64 ).split(',')[1]即开启了压缩就传压缩后的图;否则开了水印就传带水印的图;两者都没开则传原图。
单张上传链路
单张上传使用 Contents API(src/common/api/upload.ts 的uploadSingleImage):
PUT /repos/{owner}/{repo}/contents/{dir}/{filename}请求体包含message(Upload image via PicX)、branch、base64 形式的content;若配置了email,还会附加committer: { name: owner, email },使提交以用户身份记录(src/utils/upload-utils.ts 的uploadImageToGitHub)。
批量上传链路(Git Database API)
批量上传采用更高效的Git Database API 四步法(uploadImagesToGitHub):
- 创建 blob:
getFileBlob把每张图的 base64 提交为POST /repos/{owner}/{repo}/git/blobs,返回 blob sha; - 获取 head:
getBranchInfo读取分支信息,得到根目录 tree sha 与 head commit sha; - 创建 tree:
createTree基于base_tree构建新 tree(mode100644、typeblob),见 src/common/api/merge.ts; - 创建 commit 并移动 ref:
createCommit以parents: [head.commit.sha]生成新 commit,createRef通过PATCH /repos/{owner}/{repo}/git/refs/heads/{branch}把分支指针指向新 commit,完成一次原子化的批量提交。
同样的 tree/commit/ref 组合也被批量删除复用:删除时将条目的sha置为null即表示从base_tree中删除对应路径(见 src/utils/image-utils.ts 的deleteImagesFromGitHub与 src/common/api/git-tree.ts 的注释)。单张删除则直接走 Contents API 的DELETE(src/common/api/delete.ts),需携带文件 sha。
文件名处理:重命名 / 哈希化 / 添加前缀 / 时间戳
src/views/upload-image/upload-image.util.ts 的generateUploadImageObject集中处理命名:
- 重命名:名称中的空格统一替换为
-; - 哈希化:默认开启(
enableHash: true),以图片对象的 uuid 作为 hash 拼入文件名,格式为名称.uuid.后缀,确保重名图片在仓库内唯一; - 添加前缀:可配置固定前缀
prefix,格式为前缀名称.uuid.后缀; - 时间戳命名:可开启
enableTimestamp,名称整体替换为毫秒时间戳;该选项与哈希化、前缀互斥——在设置页切换时会自动关闭其他两项(见 src/views/picx-settings/picx-settings.vue 的onTimestampNamingChange);同一毫秒内批量添加时通过lastTimestamp + 1递增保证批内唯一。
五、图片链接生成:内置规则、自定义规则与格式转换
这是 PicX 的核心价值点:上传完成即生成可直接使用的图片链接,且支持多 CDN 规则自由切换。
链接规则模板
ImageLinkRuleModel(src/common/model/image.ts)将规则抽象为带占位符的 URL 模板。生成时(src/utils/image-link-utils.ts 的generateImageLink)用实际值替换四个占位符:
| 占位符 | 替换值 |
|---|---|
{{owner}} | 仓库属主 |
{{repo}} | 仓库名 |
{{branch}} | 分支名 |
{{path}} | 图片在仓库内的完整路径 |
内置 5 种预设规则(初始值见 src/stores/modules/user-settings/index.ts):
// GitHub Pages https://{{owner}}.github.io/{{repo}}/{{path}} // GitHub 原始文件 https://github.com/{{owner}}/{{repo}}/raw/{{branch}}/{{path}} // jsDelivr CDN https://cdn.jsdelivr.net/gh/{{owner}}/{{repo}}@{{branch}}/{{path}} // Statically CDN https://cdn.statically.io/gh/{{owner}}/{{repo}}@{{branch}}/{{path}} // 国内 jsDelivr 镜像 https://jsd.cdn.zzko.cn/gh/{{owner}}/{{repo}}@{{branch}}/{{path}}自定义配置链接规则:设置页提供ADD_IMAGE_LINK_TYPE_RULE/UPDATE_IMAGE_LINK_TYPE_RULE/DEL_IMAGE_LINK_TYPE_RULE三个动作(src/stores/modules/user-settings/index.ts),支持新增、编辑、删除规则,编辑时经imgLinkRuleVerification校验规则合法性(如必须包含必要占位符),满足任意自建域名或 CDN 前缀的场景。
链接格式转换
上传后支持一键复制链接,并可在Markdown / HTML / BBCode三种格式间自由转换(imageLinkFormat,默认关闭、选中 Markdown):
// Markdown imageName // HTML <img src="imageLink" alt="imageName" /> // BBCode [img]imageLink[/img]transformImageLink(src/utils/image-link-utils.ts)在复制前按所选格式替换imageLink(生成的链接)与imageName(图片文件名去后缀)。批量复制(batchCopyImageLinks)则把多张图的链接按行拼接后一次性写入剪贴板,对应 README 中的"批量复制多张图片链接"。
六、图片压缩与图片水印
图片压缩(浏览器端编码)
PicX 内置高效压缩算法,可配置上传前自动压缩。压缩在浏览器端完成,不经过任何服务器:
- 编码器枚举
CompressEncoderEnum(src/common/model/image.ts)提供mozJPEG / avif / webP / png四种;默认开启压缩且编码器为webP; - 实现上基于
@jsquash/*系列 WebAssembly 编解码库,由 src/services/image-codec.ts 的encodeImage创建独立 Web Worker(src/workers/image-codec.worker.ts)执行编码,任务结束即worker.terminate()释放资源,避免长时间占用主线程; - 仅对
png / jpg / jpeg / webp / avif生效(isNeedCompress,见 src/utils/file-utils.ts)。
图片水印
src/utils/add-watermark.ts 使用 Canvas 2D 绘制水印,配置项与默认值如下(默认值见 src/stores/modules/user-settings/index.ts):
| 配置项 | 说明 | 默认值 |
|---|---|---|
text | 水印文字 | PicX |
fontSize | 字号 | 50 |
position | 位置:leftTop/leftBottom/rightTop/rightBottom/fullScreen | rightBottom |
textColor | 文字颜色(十六进制) | #FFFFFF |
opacity | 透明度 | 0.5 |
rotate | 全屏水印旋转角度(度) | -20 |
gap | 全屏水印平铺间距(px) | 80 |
单角水印通过strokeText + fillText绘制带描边的文字;fullScreen全屏模式下则以旋转矩阵在画布上按gap平铺,形成满幅斜纹水印。水印同样只对png / jpg / jpeg / webp / avif生效。
七、一键部署 GitHub Pages 与自定义域名
README 将 GitHub Pages 列为内置链接规则之一,与之配套的是一键部署能力。部署链路在 src/components/deploy-status-bar/deploy-status-bar.util.ts 的deployGhPages与 src/common/api/branch.ts 的checkoutGhPagesBranch中实现:
- 同步 CNAME:先把设置里的自定义域名同步到图床仓库当前分支根目录的
CNAME文件(src/common/api/deploy.ts 的syncCloudCnameFile),包含规范化(去协议、去路径、小写)与格式校验(isValidCustomDomain);同步失败则中断部署; - 检查 gh-pages 分支:存在则先删除,再从当前分支复制创建(
POST /repos/{owner}/{repo}/git/refs,ref: refs/heads/gh-pages); - 等待部署生效:由于 GitHub Pages 部署需要时间,源码以
setTimeout(..., 50000)(约 50 秒)模拟部署进程,成功后自动把图片链接规则切换为GitHub Pages,并把部署状态写入仓库根目录的.deploy文件(saveCloudDeployInfo)。
自定义域名与.settings中的customDomain保持一致,保证部署结果与设置一致;域名置空时会清理仓库中的 CNAME 文件。
八、设置云端同步、PWA 与暗夜模式
设置云端同步
用户设置(UserSettingsModel,见 src/common/model/user-settings.ts)不仅保存在浏览器 LocalStorage,还可同步到图床仓库根目录的.settings文件(src/common/api/settings.ts)。由于水印文字等可能包含中文,源码特意实现了UTF-8 安全的 Base64 编解码(TextEncoder/TextDecoder配合btoa/atob),避免window.btoa对非 Latin1 字符抛异常;文件不存在则创建(Init settings via PicX),存在则带 sha 更新(Update settings via PicX)。
本地存储统一使用PICX_IH_前缀(src/common/constant/storage.ts):LocalStorage 保存CONFIG(用户配置)、SETTINGS(用户设置)、MANAGEMENT(管理页状态)、AUTHORIZATION(授权信息),SessionStorage 保存GLOBAL_SETTINGS(全局设置)。
PWA 支持
PWA 由 src/plugins/vite/pwa.ts 配置(vite-plugin-pwa,registerType: 'autoUpdate'),manifest 使用 public/logo@192x192.png 与 public/logo@512x512.png 作为应用图标。Workbox 除预缓存静态资源外,还做了两类运行时缓存:
- 图片 CDN 缓存:对 GitHub raw / GitHub Pages / jsDelivr / Statically / 国内 jsDelivr 域下的图片资源采用
StaleWhileRevalidate策略(缓存名picx-image-hosting-runtime,最多 500 条、保留 30 天),实现离线秒开;由于<img>请求为 no-cors 的 opaque 响应,cacheableResponse.statuses显式放行[0, 200]; - 编解码器 wasm 缓存:
CacheFirst缓存图片编解码用的.wasm文件,加速压缩模块加载。
配套的 src/utils/image-cache-utils.ts 提供purgeImageRuntimeCache:在覆盖上传、删除、移动、重命名成功后按仓库路径后缀清理缓存条目,避免管理页展示已被替换或删除的旧图(清理失败不影响主流程)。
暗夜模式与 i18n
- 暗夜模式:
ThemeModeEnum(src/common/model/user-settings.ts)支持system(跟随系统)/light/dark三种模式,默认system,由 src/utils/set-theme-mode.ts 应用到全局; - i18n:支持中文简体、中文繁体、英文三种语言(语言包见 src/locales/zh-CN.json、src/locales/zh-TW.json、src/locales/en.json),全局设置中可切换。
九、本地开发、构建与测试
仓库 package.json 提供完整的前端工程脚本:
# 安装依赖(pnpm 11.18.0) pnpm install # 本地开发 pnpm dev # 类型检查(vue-tsc + tsc) pnpm typecheck # 单元测试(Vitest) pnpm test # E2E 测试(Playwright) pnpm test:e2e # 代码规范(ESLint + Stylelint) pnpm lint pnpm lint:style # 生产构建 pnpm build # 一键全量校验:lint + style + typecheck + test + build pnpm verify单测覆盖了目录图片列表 store(tests/unit/dir-image-list-store.test.ts)与文件工具函数(tests/unit/file-utils.test.ts),E2E 冒烟测试见 tests/e2e/smoke.spec.ts。
十、小结
PicX 用纯前端 + GitHub API 的组合,实现了一条完整自洽的图床链路:OAuth/Token 登录 → 仓库与多级目录配置 → 拖拽/粘贴/选择图片 → 压缩与水印处理 → Git Database API 批量提交 → 模板化生成链接 → 多格式复制 → 管理页批量删除与部署 GitHub Pages。其"数据存进用户自己的仓库、链接走公开 CDN"的架构,既保证了数据主权,又无需自建存储与流量服务,是理解"以公开平台 API 构建个人工具"这一工程范式的高质量参考实现。
如果想要深入代码,推荐从 src/utils/upload-utils.ts(上传核心流程)、src/utils/image-link-utils.ts(链接生成)、src/stores/modules/user-settings/index.ts(全部设置默认值)三个文件读起。
- 开发工具
- 前端
【免费下载链接】picx
🏞️ 一款基于 GitHub API 开发的图床工具,提供图片上传托管和生成图片链接。
相关推荐
终极Mac时间管理神器:这款开源计时器让你效率翻倍! ⏰
终极Mac时间管理神器:这款开源计时器让你效率翻倍! ⏰ 在快节奏的数字时代,高效的时间管理已成为Mac用户的必备技能。今天为您推荐一款专为macOS设计的开源
开发工具前端TomatoBar:macOS菜单栏上最简洁的番茄钟应用
TomatoBar:macOS菜单栏上最简洁的番茄钟应用 TomatoBar是一款专为macOS设计的轻巧高效的菜单栏番茄钟计时器,基于著名的番茄工作法,帮助用
开发工具前端如何快速上手PicX:10分钟完成GitHub图床配置
如何快速上手PicX:10分钟完成GitHub图床配置 PicX是一款基于GitHub API开发的免费图床工具,提供图片上传托管、生成图片链接和常用图片工具箱
开发工具前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考