AI摘要:Afilmory是一个现代化的照片画廊网站,使用React和TypeScript构建,支持从多个存储源(如S3、GitHub)自动同步照片。其核心功能包括高性能WebGL图像渲染、响应式布局、EXIF信息显示和多种图像处理支持。该平台还提供增量同步、i18n多语言支持,并支持社交媒体分享。通过Docker可进行部署,并具有可定制的存储和图像处理功能。

Powered by AISummary.

Afilmory (/əˈfɪlməri/,“uh-FIL-muh-ree”)是为个人摄影网站创建的一个术语,融合了自动对焦 (AF)、光圈(光线控制)、胶片(复古媒介)和记忆(捕捉到的瞬间)。

一个使用 React + TypeScript 构建的现代照片库网站,支持从多个存储源(S3、GitHub)自动同步照片,具有高性能 WebGL 渲染、砌体布局、EXIF 信息显示、缩略图生成等功能。

演示: https://afilmory.innei.in

请输入图片描述

核心功能

🖼️高性能 WebGL 图像渲染器- 具有平滑缩放和平移操作的自定义 WebGL 组件
📱响应式 Masonry 布局- 由 Masonic 提供支持,可适应不同的屏幕尺寸
🎨现代 UI 设计- 使用 Tailwind CSS 和 Radix UI 组件库构建
⚡增量同步- 智能变化检测,仅处理新的或修改过的照片
🌐 i18n - 多语言支持
🔗 OpenGraph - 用于社交媒体共享的 OpenGraph 元数据

图像处理

🔄 HEIC/HEIF 格式支持- 自动转换 Apple 设备的 HEIC 格式
📷 TIFF 格式支持- 自动转换 TIFF 格式
🖼️智能缩略图生成- 多尺寸缩略图,优化加载性能
📊 EXIF 信息显示- 完整的拍摄参数,包括相机型号、焦距、光圈等。
🌈 Blurhash Placeholders - 优雅的图像加载体验
📱 Live Photo 支持- 检测并显示 iPhone Live Photos

高级功能

🎛️ Fujifilm Recipe - 读取并显示富士相机胶片模拟设置
🔍全屏查看器- 支持手势的图像查看器
🏷️文件系统标签- 根据文件系统自动生成的标签
⚡并发处理- 多进程/多线程并发处理支持
🗂️多存储支持- S3、GitHub 和其他存储后端
📷分享图片- 将图片分享到社交媒体或将 iframe 嵌入到您的网站
🏗️ 技术架构

前端技术栈

React 19 - 带编译器的最新 React 版本
TypeScript - 完整的类型安全
Vite - 现代构建工具
Tailwind CSS - Atomic CSS 框架
Radix UI - 可访问的组件库
Jotai——国家管理
TanStack 查询- 数据获取和缓存
React Router 7 - 路由管理
i18next——国际化

构建系统

Node.js - 服务器端运行时
夏普——高性能图像处理
AWS SDK - S3存储操作
工作线程/集群- 并发处理
EXIF-Reader - EXIF 数据提取

存储架构

采用适配器模式设计,支持多种存储后端:

S3 兼容存储- AWS S3、MinIO、阿里云 OSS 等。
GitHub 存储- 使用 GitHub 存储库作为图像存储
🚀 快速入门

Docker 部署

要求

Node.js 18+
至少 4GB RAM(用于图像处理)

1.克隆项目

git clone https://github.com/Afilmory/Afilmory.git
cd photo-gallery-site

2.安装依赖项

pnpm install

3.配置

创建.env文件:

# S3 Storage Keys
S3_ACCESS_KEY_ID=your_access_key_id
S3_SECRET_ACCESS_KEY=your_secret_access_key

创建builder.config.json存储配置和其他选项的文件:

{
  "storage": {
    "provider": "s3",
    "bucket": "my-photos",
    "region": "us-east-1",
    "prefix": "photos/",
    "customDomain": "https://cdn.example.com",
    "endpoint": "https://s3.amazonaws.com"
  }
}
  1. 站点配置

    复制并编辑配置文件:

cp config.example.json config.json

编辑config.json:

{
  "name": "My Afilmory",
  "title": "My Afilmory",
  "description": "Capturing beautiful moments in life",
  "url": "https://afilmory.example.com",
  "accentColor": "#007bff", // Optional, set theme color
  "author": {
    "name": "Your Name", // Required, set author name
    "url": "https://example.com", // Required, set author homepage
    "avatar": "https://example.com/avatar.png" // Required, set author avatar
  },
  "social": {
    // Optional, set social accounts
    "twitter": "@yourusername"
  },
  "feed": {
    "folo": { // Optional, set Folo RSS claim
      "challenge": {
        "feedId": "155982289762921472",
        "userId": "41312624216137728"
      }
    }
  }
}
  1. 建立照片清单

# Initial build
pnpm run build:manifest

# Incremental update
pnpm run build:manifest

# Force full update
pnpm run build:manifest -- --force

6.启动开发服务器

pnpm dev

⚙️ 配置选项

远程存储库配置(repo)

要在CI中实现增量构建,需要配置一个缓存仓库,该仓库会在每次构建前拉取缓存,并在构建完成后上传构建结果。

{
  "repo": {
    "enable": true,
    "url": "https://github.com/username/gallery-assets"
  }
}

这将自动从远程存储库中提取资源,避免每次重建。

为了实现上传到git仓库,需要提供一个,GIT_TOKEN并将其写入.env文件中。

存储配置(storage)


provider: 存储提供商 ( s3| github)
bucket:S3 存储桶名称
region:S3 区域
endpoint:S3 端点(可选)
prefix:文件前缀
customDomain:自定义域
excludeRegex:用于排除文件的正则表达式(可选)

构建选项(options)

defaultConcurrency:默认并发
enableLivePhotoDetection:启用实时照片检测
showProgress:显示构建进度
showDetailedStats:显示详细统计数据

性能配置(performance)

 worker.workerCount:工作进程数
worker.timeout:工作者超时(毫秒)
worker.useClusterMode:启用集群模式

日志配置(logging)

verbose:详细日志记录
level:日志级别(info||| )warnerrordebug
outputToFile:输出到文件

CLI 命令

构建命令

# View help
pnpm run build:manifest -- --help

# Incremental update (default)
pnpm run build:manifest

# Force full update
pnpm run build:manifest -- --force

# Only regenerate thumbnails
pnpm run build:manifest -- --force-thumbnails

# Only regenerate manifest
pnpm run build:manifest -- --force-manifest

开发命令

# Start development server
pnpm dev

# Build production version
pnpm build

笔记

确保您的 S3 存储桶已包含照片文件
如果使用远程存储库,builder.config.json请先配置
🔧 高级用法

自定义存储提供商

实现StorageProvider接口以支持新的存储后端:

import { StorageProvider } from './src/core/storage/interfaces'

class MyStorageProvider implements StorageProvider {
  async getFile(key: string): Promise<Buffer | null> {
    // Implement file retrieval logic
  }

  async listImages(): Promise<StorageObject[]> {
    // Implement image list retrieval logic
  }

  // ... other methods
}

自定义图像处理

在目录中添加自定义处理器src/core/image/:

export async function customImageProcessor(buffer: Buffer) {
  // Custom image processing logic
  return processedBuffer
}

GitHub: https://github.com/Afilmory/Afilmory Demo: https://afilmory.innei.in