# RandBG API - 随机背景图片服务

[![Cloudflare Workers](https://img.shields.io/badge/Cloudflare-Workers-F38020?logo=cloudflare&logoColor=white)](https://workers.cloudflare.com/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Demo](https://img.shields.io/badge/在线体验-randbg.smyhub.com-28a745)](https://randbg.smyhub.com)

> 一个基于 **Cloudflare Workers** 部署的轻量级随机背景图片 API，支持自动识别设备类型（移动端/桌面端），并提供优雅的 Web 演示界面。

---

## 在线体验

- **在线演示**: [https://randbg.smyhub.com](https://randbg.smyhub.com)
- **GitHub 仓库**: [https://github.com/shumengya/randbg-api](https://github.com/shumengya/randbg-api)

---

## 特性

- **自动设备识别**：根据 User-Agent 和 Client Hints 自动判断移动端/桌面端
- **双重响应格式**：支持 `302 Redirect` 直接跳转图片，或 `JSON` 返回图片元数据
- **静态资源优化**：使用 WebP 格式，配合 Cloudflare 静态资源缓存，加载极速
- **智能构建流程**：`build.py` 自动将原图转换为编号 WebP 并生成 `manifest.json`
- **一体化部署**：Worker 负责 API 逻辑，静态页面与图片通过 Assets 提供，单次部署即发布前后端
- **零成本部署**：基于 Cloudflare Workers Free Tier，完全免费

---

## API 文档

### `GET /api/random`

随机返回一张背景图片。

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `mode` | string | `auto` | 强制指定类型：`auto` / `mobile` / `desktop` |
| `orientation` | string | `auto` | 屏幕方向：`portrait` / `landscape` |
| `device` | string | `auto` | 设备类型：`mobile` / `desktop` |
| `format` | string | `redirect` | 响应格式：`redirect`（302 跳转）/ `json` |

**示例请求：**

```bash
# 默认 302 跳转到随机图片
curl https://randbg.smyhub.com/api/random

# 返回 JSON
curl https://randbg.smyhub.com/api/random?format=json
# 响应：
# {
#   "variant": "desktop",
#   "folder": "desketop-image",
#   "filename": "7.webp",
#   "url": "https://randbg.smyhub.com/desketop-image/7.webp",
#   "count": 19
# }

# 强制使用移动端图片
curl https://randbg.smyhub.com/api/random?mode=mobile

# 强制桌面端并返回 JSON
curl https://randbg.smyhub.com/api/random?mode=desktop&format=json
```

### `GET /api/list`

返回各变体的图片清单与统计信息。

```bash
curl https://randbg.smyhub.com/api/list
```

**响应示例：**

```json
{
  "generated_at": "2026-05-18T11:45:45.514521+00:00",
  "variants": {
    "mobile": {
      "folder": "mobile-image",
      "count": 6,
      "images": ["1.webp", "2.webp", "3.webp", "4.webp", "5.webp", "6.webp"]
    },
    "desktop": {
      "folder": "desketop-image",
      "count": 19,
      "images": ["1.webp", "2.webp", ...]
    }
  }
}
```

### `GET /manifest.json`

静态清单文件，由 `build.py` 自动生成，记录各变体的目录与文件名列表。

---

## 技术栈

| 层级 | 技术 |
|------|------|
| Runtime | [Cloudflare Workers](https://workers.cloudflare.com/) |
| 静态托管 | Cloudflare Workers Static Assets |
| 构建脚本 | Python 3 + [Pillow](https://pillow.readthedocs.io/) |
| 前端 | Vanilla HTML / CSS / JS |

---

## 项目结构

```
randbg-api/
├── src/
│   ├── worker.js              # Workers 入口路由
│   ├── api/
│   │   ├── random.js          # /api/random 接口逻辑
│   │   └── list.js            # /api/list 接口逻辑
│   └── lib/
│       └── background.js      # 通用工具（清单加载、设备识别、URL 构建）
├── public/
│   ├── index.html             # 演示与文档页面
│   ├── manifest.json          # 图片清单（build.py 生成）
│   ├── _headers               # 静态资源 HTTP 响应头
│   ├── mobile-image/          # 移动端 WebP 图片（构建产物）
│   └── desketop-image/        # 桌面端 WebP 图片（构建产物）
├── mobile-image/              # 原始图片（本地工作目录，不提交到 Git）
├── desketop-image/            # 原始图片（本地工作目录，不提交到 Git）
├── build.py                   # 构建脚本：原图 → WebP + manifest.json
├── wrangler.toml              # Workers 部署配置
├── package.json               # 依赖与脚本
└── README.md                  # 本文档
```

> **注意**：根目录下的 `mobile-image/` 和 `desketop-image/` 仅用于本地存放原始素材，不应提交到 GitHub。`build.py` 会将转换后的编号 WebP 输出到 `public/` 目录，只有 `public/` 下的内容会被部署。

---

## 部署指南

### 前置条件

- [Cloudflare 账号](https://dash.cloudflare.com/)
- [Node.js](https://nodejs.org/) 18+
- [Python 3](https://python.org/) 3.9+
- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/)

### 1. 克隆项目

```bash
git clone https://github.com/shumengya/randbg-api.git
cd randbg-api
```

### 2. 安装依赖

```bash
npm install
```

### 3. 准备图片

将原始图片放入对应目录：

```
mobile-image/        # 竖屏图片（移动端）
desketop-image/      # 横屏图片（桌面端）
```

支持格式：`.jpg` `.jpeg` `.png` `.bmp` `.gif` `.tif` `.tiff` `.webp`

### 4. 构建 WebP 与清单

```bash
python3 build.py
```

脚本会自动完成以下工作：
1. 将原图转换为高质量编号 WebP（`1.webp` `2.webp` ...）
2. 生成 `public/manifest.json`
3. 将转换后的文件输出到 `public/` 部署目录

如果 `public/` 下已有序号 WebP 且没有原图，脚本会**保留现有文件**，不会误删。

### 5. 本地预览

```bash
npm run dev
```

默认在 `http://localhost:8787` 启动预览。

### 6. 部署到 Cloudflare

```bash
npm run deploy
```

Wrangler 会将 `src/worker.js` 打包为 Worker，同时将 `public/` 作为静态 Assets 一起发布。

---

## 目录约定

- **`public/mobile-image/`**：竖屏图片（移动端）
- **`public/desketop-image/`**：横屏图片（桌面端）
  - 注意拼写沿用历史目录名，API 内部已兼容
- **`public/manifest.json`**：构建产物，API 运行时通过内部请求读取该清单

---

## 注意事项

1. **原图不上传**：根目录下的 `mobile-image/` 和 `desketop-image/` 仅用于本地构建，已配置 `.gitignore` 避免误提交。GitHub 仓库中只保留构建后的 `public/` 资源。
2. **图片版权**：请确保上传的图片拥有合法使用权或来自版权友好的来源。
3. **Worker 体积限制**：静态资源通过 Cloudflare Assets 提供，不占用 Worker 脚本 4 MiB 限制，可放心使用大量图片。
4. **缓存策略**：`public/_headers` 已为图片配置了 `immutable` 长期缓存，为 `manifest.json` 配置了 5 分钟缓存。如需更新图片，请重新运行 `build.py` 并部署。

---

## 开源协议

本项目基于 [MIT License](LICENSE) 开源。

---

## 贡献

欢迎提交 Issue 和 Pull Request！如果你有任何建议或发现问题，请随时反馈。

---

<p align="center">
  Made with ❤️ by <a href="https://github.com/shumengya">shumengya</a>
</p>
