Weave your photos into stunning galleries with AI-powered automation.
Photoloom is a free, open-source tool that transforms your messy photo folders into a beautiful, searchable static website. Just point it at your photos—it uses AI to auto-tag, describe, and add copyright watermarks, then generates a fast static gallery you can host anywhere for free.
No subscriptions. No privacy concerns. No hosting fees. Just your photos—beautifully presented.
- AI-first preprocessing - Automatically tags, categorizes, and describes your photos using AI
- Truly free hosting - Generates static sites that can be hosted on Netlify, GitHub Pages, Cloudflare Pages, or any static host
- Privacy-first - Runs locally on your machine. Your photos never leave your computer until you deploy
- Incremental builds - Only reprocess new photos, saving time and AI API tokens
- Copyright protection - Built-in watermarking keeps your work protected
- Hugo-powered - Leverages the proven Hugo static site generator ecosystem
# 1. Clone and configure
git clone https://github.com/yourusername/photoloom.git
cd photoloom
cp .env.example .env
# 2. Add your photos
cp your_photos/* ./photos/
# 3. Add your API key (or use 'none' for local-only)
# Edit .env and set OPENAI_API_KEY=your-key-here
# 4. Build
go run ./cmd/build
# 5. Preview locally
cd hugo && hugo serverPhotoloom analyzes every photo using AI to extract:
- Categories - Portrait, Landscape, Wildlife, Nature, Architecture, Events, Travel, Family, and more
- Tags - 2-5 relevant keywords per photo
- Descriptions - AI-generated 1-2 sentence descriptions
- Colors - Dominant colors in hex format
Supported AI providers:
- OpenAI - Uses GPT-4o vision (configurable model)
- Ollama - Local AI using llava or other vision models
- None - Skip AI and use EXIF data only
Automatically extracts camera metadata:
- Date taken
- Camera make & model
- Lens information
- ISO, aperture, shutter speed
- Focal length
- Image dimensions
- Web optimization - Resizes photos for optimal web display (default: 1600px)
- Thumbnail generation - Creates thumbnails for gallery views (default: 400px)
- Watermarking - Adds customizable copyright watermark to large photos
- Format conversion - Converts to optimized JPEG format
- Folder-based albums - Automatically creates albums from folder structure
- AI-category grouping - Optional grouping by AI-detected category
- Date-based sorting - Photos sorted by EXIF date or file modification time
- Color grouping - Groups photos by dominant color palette
- Generates clean Hugo content files with full metadata
- Built-in gallery theme with lightbox viewer
- Taxonomy support for categories, tags, and colors
- Responsive design for mobile and desktop
- Go 1.21+ - For building the CLI tool
- Hugo 0.110+ - For generating the static site
- OpenAI API key or Ollama (optional) - For AI metadata extraction
-
Clone the repository:
git clone https://github.com/yourusername/photoloom.git cd photoloom -
Copy the environment file:
cp .env.example .env
-
Add your photos to the
photosdirectory (or configure a different path inconfig.yaml) -
Configure your AI provider (optional):
- For OpenAI: Add your API key to
.env - For Ollama: Ensure Ollama is running locally
- For no AI: Set
ai.provider: "none"in config.yaml
- For OpenAI: Add your API key to
-
Build:
go run ./cmd/build
-
Preview:
cd hugo && hugo server
All configuration is in config.yaml:
paths:
photosDir: "./photos" # Your source photos
cacheDir: "./cache" # Processed metadata cache
outputDir: "./output" # Final static site
images:
thumbnail:
width: 400 # Thumbnail size
height: 400
quality: 80
web:
width: 1600 # Web image size (0 = auto)
height: 0
quality: 85
watermarkThreshold: 1080 # Only watermark images > this width
watermark:
text: "© Your Name" # Watermark text
opacity: 0.7 # 0.0 - 1.0
fontPath: "fonts/AlexBrush-Regular.ttf"
position: "bottom-right" # bottom-left, top-right, top-left
ai:
provider: "openai" # "openai", "ollama", or "none"
openai:
apiKey: "$OPENAI_API_KEY"
model: "gpt-4o-mini"
concurrency: 4
ollama:
baseURL: "http://localhost:11434"
model: "llava"
albums:
groupBy: ["folder"] # How to group photos into albums
minPhotos: 1 # Minimum photos per album
hugo:
theme: "gallery"
flags:
- "--minify"
- "--gc"
build:
workers: 4 # Parallel processing workersgo run ./cmd/build # Full build
go run ./cmd/build -skip-ai # Skip AI processing (use cached)
go run ./cmd/build -skip-images # Skip image processing
go run ./cmd/build -skip-hugo # Skip Hugo build
go run ./cmd/build -clean # Clear cache before buildingphotoloom/
├── cmd/build/ # Main CLI entry point
├── internal/
│ ├── ai/ # AI provider (OpenAI, Ollama)
│ ├── config/ # Configuration loading
│ ├── exif/ # EXIF metadata extraction
│ ├── hugo/ # Hugo content generator
│ ├── imageproc/ # Image processing & watermarking
│ ├── metadata/ # Metadata storage
│ └── colors/ # Color grouping logic
├── hugo/
│ ├── config.yaml # Hugo configuration
│ └── themes/gallery/ # Custom gallery theme
├── fonts/ # Watermark fonts
├── config.yaml # Photoloom configuration
├── .env # API keys (not committed)
└── .env.example # Environment template
Photoloom generates a completely static site. Deploy anywhere for free:
cd hugo
hugo --theme=gallery --destination=../docs
# Enable GitHub Pages in repo settings, point to /docs- Connect your repo to Netlify
- Build command:
go run ./cmd/build - Publish directory:
output
- Connect your repo to Cloudflare
- Build command:
go run ./cmd/build - Publish directory:
output
Simply upload the output/ directory to any web server.
Edit hugo/config.yaml to use a different Hugo theme, or create your own in hugo/themes/.
- Add your font file to the
fonts/directory - Update
config.yamlwith your font path and watermark text - Rebuild
Modify the ai.prompt section in config.yaml to customize how AI analyzes your photos.
Contributions welcome! Please open an issue or submit a PR.
MIT License - see LICENSE for details.