mirror of
https://github.com/Afilmory/afilmory
synced 2026-02-01 22:48:17 +00:00
refactor: clean up builder configuration and enhance README with detailed features and setup instructions
Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
382
README.md
382
README.md
@@ -1,119 +1,363 @@
|
||||
# Photo Gallery Site
|
||||
|
||||
⚠️警告:此项目多数代码都由 Claude 4 生成,请谨慎使用。
|
||||
一个现代化的照片画廊网站,采用 React + TypeScript 构建,支持从多种存储源(S3、GitHub)自动同步照片,具有高性能 WebGL 渲染、瀑布流布局、EXIF 信息展示、缩略图生成等功能。
|
||||
|
||||
一个现代化的照片画廊网站,支持从 S3 存储自动同步照片,具有瀑布流布局、EXIF 信息展示、缩略图生成等功能。
|
||||
## 🌟 特性
|
||||
|
||||
Preview: https://gallery.innei.in
|
||||
### 核心功能
|
||||
|
||||
## 特点
|
||||
- 🖼️ **高性能 WebGL 图像渲染器** - 基于自研 WebGL 组件,支持流畅的缩放、平移操作
|
||||
- 📱 **响应式瀑布流布局** - 采用 Masonic 实现,自适应不同屏幕尺寸
|
||||
- 🎨 **现代化 UI 设计** - 基于 Tailwind CSS 和 Radix UI 组件库
|
||||
- ⚡ **增量同步** - 智能检测文件变化,仅处理新增或修改的照片
|
||||
|
||||
- 高性能 WebGL 图像渲染器
|
||||
- HEIC/HEIF 格式支持
|
||||
- 支持缩略图生成
|
||||
- 支持 EXIF 信息展示
|
||||
- 瀑布流布局
|
||||
- 支持富士胶片模拟信息读取
|
||||
### 图像处理
|
||||
|
||||
## 环境配置
|
||||
- 🔄 **HEIC/HEIF 格式支持** - 自动转换 Apple 设备的 HEIC 格式
|
||||
- 🖼️ **智能缩略图生成** - 多尺寸缩略图,优化加载性能
|
||||
- 📊 **EXIF 信息展示** - 完整的拍摄参数,包括相机型号、焦距、光圈等
|
||||
- 🌈 **Blurhash 占位符** - 优雅的图片加载体验
|
||||
- 📱 **Live Photo 支持** - 检测并展示 iPhone Live Photo
|
||||
|
||||
创建 `.env` 文件并配置以下环境变量:
|
||||
### 高级功能
|
||||
|
||||
- 🎛️ **富士胶片模拟** - 读取和展示富士相机的胶片模拟设置
|
||||
- 🔍 **全屏查看器** - 支持手势操作的图片查看器
|
||||
- 🏷️ **智能标签** - 基于 EXIF 数据自动生成标签
|
||||
- ⚡ **并发处理** - 支持多进程/多线程并发处理
|
||||
- 🗂️ **多存储支持** - S3、GitHub 等多种存储后端
|
||||
|
||||
## 🏗️ 技术架构
|
||||
|
||||
### 前端技术栈
|
||||
|
||||
- **React 19** - 使用最新的 React 版本和 Compiler
|
||||
- **TypeScript** - 完整的类型安全
|
||||
- **Vite** - 现代化构建工具
|
||||
- **Tailwind CSS** - 原子化 CSS 框架
|
||||
- **Radix UI** - 无障碍组件库
|
||||
- **Jotai** - 状态管理
|
||||
- **TanStack Query** - 数据获取和缓存
|
||||
- **React Router 7** - 路由管理
|
||||
|
||||
### 构建系统
|
||||
|
||||
- **Node.js** - 服务端运行时
|
||||
- **Sharp** - 高性能图像处理
|
||||
- **AWS SDK** - S3 存储操作
|
||||
- **Worker Threads/Cluster** - 并发处理
|
||||
- **EXIF-Reader** - EXIF 数据提取
|
||||
|
||||
### 存储架构
|
||||
|
||||
采用适配器模式设计,支持多种存储后端:
|
||||
|
||||
- **S3 兼容存储** - AWS S3、MinIO、阿里云 OSS 等
|
||||
- **GitHub 存储** - 使用 GitHub 仓库作为图片存储
|
||||
|
||||
## 📦 项目结构
|
||||
|
||||
```
|
||||
photo-gallery-site/
|
||||
├── apps/web/ # 主应用
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # React 组件
|
||||
│ │ │ ├── ui/ # UI 组件库
|
||||
│ │ │ └── common/ # 通用组件
|
||||
│ │ ├── core/ # 核心构建系统
|
||||
│ │ │ ├── builder/ # 主构建器
|
||||
│ │ │ ├── storage/ # 存储适配器
|
||||
│ │ │ ├── image/ # 图像处理
|
||||
│ │ │ ├── photo/ # 照片处理
|
||||
│ │ │ └── worker/ # 并发处理
|
||||
│ │ ├── modules/ # 功能模块
|
||||
│ │ ├── pages/ # 页面组件
|
||||
│ │ └── data/ # 数据文件
|
||||
│ ├── public/ # 静态资源
|
||||
│ └── scripts/ # 构建脚本
|
||||
├── packages/webgl-viewer/ # WebGL 图像查看器
|
||||
├── config/ # 配置文件
|
||||
└── docs/ # 文档
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Node.js 18+
|
||||
- 至少 4GB RAM(用于图像处理)
|
||||
|
||||
### 1. 克隆项目
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Iris-Photo-Gallery/Iris.git
|
||||
cd photo-gallery-site
|
||||
```
|
||||
|
||||
### 2. 安装依赖
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### 3. 环境配置
|
||||
|
||||
创建 `.env` 文件:
|
||||
|
||||
```env
|
||||
# S3 配置
|
||||
# S3 存储配置
|
||||
S3_REGION=us-east-1
|
||||
S3_ACCESS_KEY_ID=your_access_key_id
|
||||
S3_SECRET_ACCESS_KEY=your_secret_access_key
|
||||
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
|
||||
S3_ENDPOINT=https://s3.amazonaws.com
|
||||
S3_BUCKET_NAME=your_bucket_name
|
||||
S3_PREFIX=photos/
|
||||
S3_CUSTOM_DOMAIN=your_custom_domain.com
|
||||
```
|
||||
|
||||
## Photo Gallery Builder
|
||||
### 4. 站点配置
|
||||
|
||||
基于适配器模式重构的照片库构建器,提供灵活的存储抽象和可配置的构建选项。
|
||||
复制并编辑配置文件:
|
||||
|
||||
### 配置文件
|
||||
```bash
|
||||
cp config.example.json config.json
|
||||
```
|
||||
|
||||
在项目根目录的 `builder.config.ts` 中可以配置构建器的各种选项:
|
||||
编辑 `config.json`:
|
||||
|
||||
```typescript
|
||||
export const builderConfig: BuilderConfig = {
|
||||
storage: {
|
||||
provider: 's3',
|
||||
bucket: 'my-bucket',
|
||||
region: 'us-east-1',
|
||||
// ... 其他存储配置
|
||||
},
|
||||
|
||||
options: {
|
||||
defaultConcurrency: 8, // 默认并发数
|
||||
maxPhotos: 5000, // 最大照片数量限制
|
||||
enableLivePhotoDetection: true, // 启用 Live Photo 检测
|
||||
showProgress: true, // 显示进度
|
||||
showDetailedStats: true, // 显示详细统计
|
||||
},
|
||||
|
||||
logging: {
|
||||
verbose: true, // 详细日志
|
||||
level: 'debug', // 日志级别
|
||||
outputToFile: false, // 是否输出到文件
|
||||
},
|
||||
|
||||
performance: {
|
||||
worker: {
|
||||
timeout: 30000, // Worker 超时时间
|
||||
},
|
||||
memoryLimit: 512, // 内存限制(MB)
|
||||
enableCache: true, // 启用缓存
|
||||
```json
|
||||
{
|
||||
"name": "我的照片画廊",
|
||||
"title": "我的照片画廊",
|
||||
"description": "记录生活中的美好瞬间",
|
||||
"url": "https://gallery.example.com",
|
||||
"accentColor": "#007bff",
|
||||
"author": {
|
||||
"name": "Your Name",
|
||||
"url": "https://example.com"
|
||||
},
|
||||
"social": {
|
||||
"twitter": "@yourusername"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 自定义存储提供商
|
||||
### 5. 构建照片清单
|
||||
|
||||
如果需要使用其他存储服务(如阿里云 OSS),可以:
|
||||
```bash
|
||||
# 首次构建
|
||||
pnpm run build:manifest
|
||||
|
||||
1. 实现新的存储提供商类
|
||||
2. 在配置中指定使用新的提供商
|
||||
# 增量更新
|
||||
pnpm run build:manifest
|
||||
|
||||
```typescript
|
||||
const builder = new PhotoGalleryBuilder({
|
||||
storage: {
|
||||
provider: 'oss', // 假设已经实现了 OSS 提供商
|
||||
bucket: 'my-oss-bucket',
|
||||
// ... OSS 特定配置
|
||||
},
|
||||
})
|
||||
# 强制全量更新
|
||||
pnpm run build:manifest -- --force
|
||||
```
|
||||
|
||||
## 🚀 使用
|
||||
|
||||
### 开发模式
|
||||
### 6. 启动开发服务器
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### 构建照片清单
|
||||
## ⚙️ 配置选项
|
||||
|
||||
### 构建器配置
|
||||
|
||||
创建 `builder.config.json` 文件进行高级配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"repo": {
|
||||
"enable": false,
|
||||
"url": "https://github.com/username/gallery-assets"
|
||||
},
|
||||
"storage": {
|
||||
"provider": "s3",
|
||||
"bucket": "my-photos",
|
||||
"region": "us-east-1",
|
||||
"prefix": "photos/",
|
||||
"customDomain": "cdn.example.com"
|
||||
},
|
||||
"options": {
|
||||
"defaultConcurrency": 8,
|
||||
"maxPhotos": 5000,
|
||||
"enableLivePhotoDetection": true,
|
||||
"showProgress": true,
|
||||
"showDetailedStats": true
|
||||
},
|
||||
"logging": {
|
||||
"verbose": true,
|
||||
"level": "info",
|
||||
"outputToFile": false
|
||||
},
|
||||
"performance": {
|
||||
"worker": {
|
||||
"workerCount": 8,
|
||||
"timeout": 30000,
|
||||
"useClusterMode": true,
|
||||
"workerConcurrency": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 配置选项说明
|
||||
|
||||
#### 存储配置 (`storage`)
|
||||
|
||||
- `provider`: 存储提供商 (`s3` | `github`)
|
||||
- `bucket`: S3 存储桶名称
|
||||
- `region`: S3 区域
|
||||
- `endpoint`: S3 端点(可选)
|
||||
- `prefix`: 文件前缀
|
||||
- `customDomain`: 自定义域名
|
||||
|
||||
#### 构建选项 (`options`)
|
||||
|
||||
- `defaultConcurrency`: 默认并发数 (1-50)
|
||||
- `maxPhotos`: 最大照片数量限制
|
||||
- `enableLivePhotoDetection`: 启用 Live Photo 检测
|
||||
- `showProgress`: 显示构建进度
|
||||
- `showDetailedStats`: 显示详细统计信息
|
||||
|
||||
#### 性能配置 (`performance`)
|
||||
|
||||
- `worker.workerCount`: Worker 进程数
|
||||
- `worker.timeout`: Worker 超时时间(毫秒)
|
||||
- `worker.useClusterMode`: 启用集群模式
|
||||
|
||||
#### 日志配置 (`logging`)
|
||||
|
||||
- `verbose`: 详细日志
|
||||
- `level`: 日志级别 (`info` | `warn` | `error` | `debug`)
|
||||
- `outputToFile`: 输出到文件
|
||||
|
||||
### 远程资源库配置
|
||||
|
||||
如果你有独立的资源仓库存储缩略图和清单:
|
||||
|
||||
```json
|
||||
{
|
||||
"repo": {
|
||||
"enable": true,
|
||||
"url": "https://github.com/username/gallery-assets"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这将自动从远程仓库拉取资源,避免每次构建。
|
||||
|
||||
## 📋 CLI 命令
|
||||
|
||||
### 构建命令
|
||||
|
||||
```bash
|
||||
# 查看帮助
|
||||
pnpm run build:manifest -- --help
|
||||
|
||||
# 增量更新(默认)
|
||||
pnpm run build:manifest
|
||||
|
||||
# 全量更新
|
||||
# 强制全量更新
|
||||
pnpm run build:manifest -- --force
|
||||
|
||||
# 仅重新生成缩略图
|
||||
pnpm run build:manifest -- --force-thumbnails
|
||||
|
||||
# 仅重新生成清单
|
||||
pnpm run build:manifest -- --force-manifest
|
||||
```
|
||||
|
||||
### 构建生产版本
|
||||
### 开发命令
|
||||
|
||||
```bash
|
||||
pnpm run build
|
||||
# 启动开发服务器
|
||||
pnpm dev
|
||||
|
||||
# 构建生产版本
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## License
|
||||
## 🚀 部署指南
|
||||
|
||||
2025 © Innei, Released under the MIT License.
|
||||
### Vercel 部署(推荐)
|
||||
|
||||
> [Personal Website](https://innei.in/) · GitHub [@Innei](https://github.com/innei/)
|
||||
1. **Fork 项目**
|
||||
|
||||
- 访问 [GitHub 仓库](https://github.com/Iris-Photo-Gallery/Iris)
|
||||
- 点击右上角的 "Fork" 按钮,将项目 fork 到你的 GitHub 账户
|
||||
|
||||
2. **在 Vercel 部署**
|
||||
- 访问 [Vercel](https://vercel.com/)
|
||||
- 使用 GitHub 账户登录
|
||||
- 点击 "New Project",选择你刚才 fork 的仓库
|
||||
- 在项目设置中添加以下环境变量(如果你使用 S3 存储):
|
||||
|
||||
```env
|
||||
S3_REGION=us-east-1
|
||||
S3_ACCESS_KEY_ID=你的 S3 访问密钥 ID
|
||||
S3_SECRET_ACCESS_KEY=你的 S3 秘密访问密钥
|
||||
S3_ENDPOINT=https://s3.amazonaws.com
|
||||
S3_BUCKET_NAME=你的 S3 存储桶名称
|
||||
S3_PREFIX=photos/
|
||||
S3_CUSTOM_DOMAIN=你的自定义域名(可选)
|
||||
```
|
||||
|
||||
3. **触发部署**
|
||||
- 配置完环境变量后,Vercel 会自动开始部署
|
||||
- 等待部署完成,你的照片画廊就上线了!
|
||||
|
||||
### 注意事项
|
||||
|
||||
- 确保你的 S3 存储桶已经包含照片文件
|
||||
- 如果使用远程资源库,需要先配置 `builder.config.json`
|
||||
|
||||
## 🔧 高级用法
|
||||
|
||||
### 自定义存储提供商
|
||||
|
||||
实现 `StorageProvider` 接口以支持新的存储后端:
|
||||
|
||||
```typescript
|
||||
import { StorageProvider } from './src/core/storage/interfaces'
|
||||
|
||||
class MyStorageProvider implements StorageProvider {
|
||||
async getFile(key: string): Promise<Buffer | null> {
|
||||
// 实现文件获取逻辑
|
||||
}
|
||||
|
||||
async listImages(): Promise<StorageObject[]> {
|
||||
// 实现图片列表获取逻辑
|
||||
}
|
||||
|
||||
// ... 其他方法
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义图像处理
|
||||
|
||||
在 `src/core/image/` 目录下添加自定义处理器:
|
||||
|
||||
```typescript
|
||||
export async function customImageProcessor(buffer: Buffer) {
|
||||
// 自定义图像处理逻辑
|
||||
return processedBuffer
|
||||
}
|
||||
```
|
||||
|
||||
## 📄 许可证
|
||||
|
||||
MIT License © 2025 Innei
|
||||
|
||||
## 🔗 相关链接
|
||||
|
||||
- [在线演示](https://gallery.innei.in)
|
||||
- [个人网站](https://innei.in)
|
||||
- [GitHub](https://github.com/innei)
|
||||
- [问题反馈](https://github.com/Iris-Photo-Gallery/Iris/issues)
|
||||
|
||||
---
|
||||
|
||||
如果这个项目对你有帮助,请给个 ⭐️ Star 支持一下!
|
||||
|
||||
@@ -6,11 +6,7 @@ import { GetObjectCommand, ListObjectsV2Command } from '@aws-sdk/client-s3'
|
||||
import { SUPPORTED_FORMATS } from '../../constants/index.js'
|
||||
import type { Logger } from '../../logger/index.js'
|
||||
import { s3Client } from '../../s3/client.js'
|
||||
import type {
|
||||
S3Config,
|
||||
StorageObject,
|
||||
StorageProvider,
|
||||
} from '../interfaces'
|
||||
import type { S3Config, StorageObject, StorageProvider } from '../interfaces'
|
||||
|
||||
// 将 AWS S3 对象转换为通用存储对象
|
||||
function convertS3ObjectToStorageObject(s3Object: _Object): StorageObject {
|
||||
@@ -123,7 +119,7 @@ export class S3StorageProvider implements StorageProvider {
|
||||
// 如果设置了自定义域名,直接使用自定义域名
|
||||
if (this.config.customDomain) {
|
||||
const customDomain = this.config.customDomain.replace(/\/$/, '') // 移除末尾的斜杠
|
||||
return `${customDomain}/${this.config.bucket}/${key}`
|
||||
return `${customDomain}/${key}`
|
||||
}
|
||||
|
||||
// 如果使用自定义端点,构建相应的 URL
|
||||
|
||||
@@ -65,12 +65,6 @@ export interface BuilderConfig {
|
||||
// Worker 数量
|
||||
workerCount: number
|
||||
}
|
||||
|
||||
// 内存使用限制(MB)
|
||||
memoryLimit: number
|
||||
|
||||
// 是否启用缓存
|
||||
enableCache: boolean
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,8 +106,6 @@ export const defaultBuilderConfig: BuilderConfig = {
|
||||
useClusterMode: true,
|
||||
workerConcurrency: 2,
|
||||
},
|
||||
memoryLimit: 512, // 512MB
|
||||
enableCache: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user