7.7 KiB
ImageRepo
A self-hosted image and video gallery application designed for organizing and viewing media collections. Originally built for managing Patreon content archives, it features automatic importing, tagging, duplicate detection, and a responsive dark-themed UI.
Features
- Gallery View - Browse images in a paginated grid with thumbnail previews
- Showcase View - Randomized masonry layout for discovery
- Image Modal - Full-size viewing with zoom, pan, and keyboard navigation
- Video Support - Playback for video files with thumbnail generation
- Tagging System - Organize images with tags (artist, character, series, rating, archive, user-defined)
- Tag Autocomplete - Quick tag entry with search suggestions
- Automatic Importing - Scans
/importdirectory on schedule or manual trigger - Archive Extraction - Supports ZIP, RAR, 7z and other archive formats
- Duplicate Detection - Perceptual hash (pHash) comparison to skip similar images
- Import Filters - Skip images by dimensions or transparency percentage
- Bulk Deletion - Delete images by tag or filter criteria
- Artist Organization - Auto-tags images based on folder structure
- Dark Theme - Easy on the eyes for extended browsing
Quick Start
Docker Compose
services:
imagerepo:
image: git.fabledsword.com/bvandeusen/imagerepo:latest
ports:
- "5000:5000"
volumes:
- ./imagerepo/db:/db # SQLite database storage
- ./imagerepo/images:/images # Imported images and thumbnails
- ./your-media:/import # Source directory to import from
environment:
- THUMBS_VERBOSE=1
- THUMBS_LOG_EVERY=50
Then visit http://localhost:5000 in your browser.
Volumes
| Path | Description |
|---|---|
/db |
Database storage (SQLite by default) |
/images |
Where imported images and thumbnails are stored |
/import |
Source directory the importer scans for new media |
Environment Variables
Database Configuration
By default, ImageRepo uses SQLite. Set DB_TYPE=postgresql to use PostgreSQL instead.
| Variable | Default | Description |
|---|---|---|
DB_TYPE |
sqlite |
Database type: sqlite or postgresql |
DB_NAME |
app.db |
Database name (SQLite filename or PostgreSQL database) |
DB_USER |
imagerepo |
PostgreSQL username |
DB_PASS |
postgres |
PostgreSQL password |
DB_HOST |
postgres |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
Import Settings
These can also be configured via the Settings page in the UI.
| Variable | Default | Description |
|---|---|---|
IMPORT_MIN_WIDTH |
0 |
Minimum image width in pixels (0 = no minimum) |
IMPORT_MIN_HEIGHT |
0 |
Minimum image height in pixels (0 = no minimum) |
IMPORT_SKIP_TRANSPARENT |
false |
Skip mostly-transparent images (PNG/GIF/WebP) |
IMPORT_TRANSPARENCY_THRESHOLD |
0.9 |
Transparency % threshold (0.0-1.0) for skipping |
IMPORT_PHASH_THRESHOLD |
2 |
Duplicate detection sensitivity (0=disabled, 1=strict, 2=normal, 5=loose, 10=very loose) |
Thumbnail Generation
| Variable | Default | Description |
|---|---|---|
THUMBS_VERBOSE |
0 |
Enable verbose logging (1, true, or yes) |
THUMBS_LOG_EVERY |
50 |
Log progress every N thumbnails |
THUMBS_BATCH_SIZE |
500 |
Process thumbnails in batches of N |
THUMBS_FFMPEG_TIMEOUT |
60 |
Timeout in seconds for video thumbnail extraction |
Archive Extraction
| Variable | Default | Description |
|---|---|---|
ARCHIVE_TMPDIR |
System temp | Directory for extracting archives |
ARCHIVE_MIN_FREE_GB |
0 |
Minimum free disk space (GB) required to start extraction (0 = disabled) |
ARCHIVE_NUM_WIDTH |
4 |
Zero-padding width for archive sequence numbers in tags |
Other
| Variable | Default | Description |
|---|---|---|
PIL_MAX_IMAGE_PIXELS |
178956970 |
Maximum image size Pillow will process (guards against decompression bombs) |
Import Behavior
The importer runs:
- Automatically every 8 hours
- Manually via the "Trigger Image Import" button in Settings
Folder Structure
The importer uses the folder structure to auto-tag images:
/import/
├── ArtistName/ # Tagged as "artist:ArtistName"
│ ├── image1.png
│ ├── image2.jpg
│ └── archive.zip # Extracted, contents tagged with "archive:archive"
├── AnotherArtist/
│ └── subfolder/
│ └── image3.png # Still tagged as "artist:AnotherArtist"
- Top-level folders become
artist:FolderNametags - Archives (ZIP, RAR, 7z, etc.) are extracted and their contents tagged with
archive:filename - Nested subfolders inherit the top-level artist tag
Supported Formats
Images: PNG, JPG, JPEG, GIF, WebP, BMP, TIFF
Videos: MP4, WebM, MKV, AVI, MOV
Archives: ZIP, RAR, 7z, and others supported by unar/7z
Settings Page
The Settings page (/settings) provides:
Admin Actions
- Trigger Image Import - Manually start an import scan
- Regenerate Thumbnails - Rebuild all thumbnails
- Reset Image Database - Clear all image records (files remain on disk)
Import Filters
Configure filtering rules that apply during import:
- Minimum dimensions
- Transparency filtering
- Duplicate detection sensitivity
Delete Images by Tag
Bulk delete all images associated with a specific tag (e.g., remove an entire artist's collection).
Clean Up Existing Images
Scan and selectively delete images that match filter criteria (transparency or dimensions).
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/random-images |
GET | Get random images for showcase |
/api/tags/search |
GET | Search tags for autocomplete |
/api/import-settings |
GET/POST | Read/write import filter settings |
/api/import-stats |
GET | Get last import statistics |
/api/filter-scan |
GET | Scan images matching filter criteria |
/api/filter-delete |
POST | Delete selected images |
/api/delete-by-tag |
POST | Delete all images with a tag |
/image/<id>/tags |
GET | List tags for an image |
/image/<id>/tags/add |
POST | Add a tag to an image |
/image/<id>/tags/remove |
POST | Remove a tag from an image |
Keyboard Shortcuts
In the image modal:
- Arrow Left/Right - Previous/Next image
- Escape - Close modal
- Click image - Toggle zoom
- Drag (when zoomed) - Pan around image
PostgreSQL Setup
To use PostgreSQL instead of SQLite:
services:
imagerepo:
image: git.fabledsword.com/bvandeusen/imagerepo:latest
ports:
- "5000:5000"
environment:
- DB_TYPE=postgresql
- DB_HOST=postgres
- DB_USER=imagerepo
- DB_PASS=your_secure_password
- DB_NAME=imagerepo
volumes:
- ./imagerepo/images:/images
- ./your-media:/import
depends_on:
- postgres
postgres:
image: postgres:15
environment:
- POSTGRES_USER=imagerepo
- POSTGRES_PASSWORD=your_secure_password
- POSTGRES_DB=imagerepo
volumes:
- ./postgres-data:/var/lib/postgresql/data
Development
Local Setup
# Clone the repository
git clone https://git.fabledsword.com/bvandeusen/imagerepo.git
cd imagerepo
# Create virtual environment
python -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
# Install dependencies
pip install -r requirements.txt
# Run with Flask dev server
flask run
Docker Build
docker build -t imagerepo .
docker run -p 5000:5000 -v ./images:/images -v ./import:/import imagerepo
License
This is a personal project. Use at your own discretion.