/photofield

Experimental fast photo viewer.

Primary LanguageGoMIT LicenseMIT


Logo

Photofield

Experimental fast photo viewer.

live demo docs License Version Image Size GitHub Actions Workflow Status Discord

Table of Contents
  1. About
  2. Getting Started
  3. Configuration
  4. Usage
  5. Maintenance
  6. Development Setup
  7. Contributing
  8. License
  9. Acknowledgements

About

Zoom to logo within a 43k images

Zoom to logo within a sample of 43k images from open-images-dataset, i7-5820K 6-Core CPU, NVMe SSD

Photofield is a photo viewer built to mainly push the limits of what is possible in terms of the number of photos visible at the same time and at the speed at which they are displayed. The goal is to be as fast or faster than Google Photos on commodity hardware while displaying more photos at the same time. It is non-invasive and can be used either completely standalone or complementing other photo gallery software.

Features

  • Seamless zoomable interface. Thanks to tiled image loading supported by OpenLayers and the API implementing tile rendering, you can switch between levels of detail seamlessly without loading a special detailed or fullscreen view.

    Seamless zoom to giraffe face

  • Progressive multi-resolution loading. Not only are thumbnails used to show a single photo quicker, the whole layout is progressively loaded, so even if you move through photos quickly or zoom around, you will almost always have some form of feedback to not lose track.

    Progressive load of a deer

  • Different layouts. Collections of photos can be displayed with different layouts. layout examples

  • Semantic search using photofield-ai. If enabled, you can search for photo contents using words like "beach sunset", "a couple kissing", or "cat eyes". semantic search for "cat eyes"

  • Tagging (alpha). You can tag and search photos with arbitrary tags. If enabled, tags are stored in the cache database and can be used to filter photos.

  • Reverse geolocation. Local, embedded reverse geolocation of ~50 thousand places via tinygpkg with neglibile overhead supported in the Timeline and Flex layouts.

  • Flexible media/thumbnail system. There are many different ways for images and thumbnails to be generated and stored. Uses FFmpeg for on-the-fly conversion, SQLite for caching, existing embedded JPEG thumbnails, Synology Moments / Photo Station thumbnails, and more.

  • Single file binary. Thanks to Go and GoReleaser, all the dependencies are packed into a single binary file for most major OSes.

  • Read-only file system based collections. Photofield never changes your photos, thumbnails or directories. You are encouraged to even mount your photos as read-only to ensure this. The file system is the source of truth, everything else is just a more or less stale cache.

  • Fast indexing. Thanks to godirwalk, file indexing practically runs at the speed of the file system 1000-10000 files/sec on fast SSD and hot cache. EXIF metadata and prominent color are extracted as separate follow-up operations and run at up to ~200 files/sec and ~1000 files/sec on a fast system.

  • Basic video support. Videos are supported, however the user experience is not great yet as there are some usability quirks. Different resolutions are supported if they have been previously transcoded, but there is no on-the-fly transcoding supported right now.

Limitations

  • No photo details (yet). There is no way to show metadata of a photo in the UI at this point.
  • Not optimized for many clients. As a lot of the normally client-side state is kept on the server, you will likely run into CPU or Memory problems with more than a few simultaneous users.
  • No user accounts. Not the focus right now. You can define separate collections for separate users based on the directory structure, but there is no authentication or authorization support.
  • Initial load can be slow. All the photos need to be laid out when you first load a page in a specific window size and configuration, which can take some time with a slow CPU and cold HDD cache.
  • No permalinks. Deep linking to images works, but it's currently not stable over time as IDs can change.

See the documentation for more information.

Built With

Getting Started

Docker

Make sure you create an empty data directory in the working directory and that you put some photos in a photos directory.

docker run -p 8080:8080 -v "$PWD/data:/app/data" -v "$PWD/photos:/app/photos:ro" ghcr.io/smilyorg/photofield

The cache database will be persisted to the data dir and the app should be accessible at http://localhost:8080. It should show the photos collection by default. For further configuration, create a configuration.yaml in the data dir.

docker-compose.yaml example

This example binds the usual Synology Moments photo directories and assumes a certain path structure, modify to your needs graciously. It also assumes you have configured the /photo and /user directories as collections in the configuration.yaml.

version: '3.3'
services:

  photofield:
    image: ghcr.io/smilyorg/photofield:latest
    ports:
      - 8080:8080
    volumes:
      - /volume1/docker/photofield/data:/app/data
      - /volume1/photo/:/photo:ro
      - /volume1/homes/ExampleUser/Drive/Moments:/exampleuser:ro

Binaries

  1. Download and unpack a release.
  2. Run ./photofield or double-click on photofield.exe to start the server.
  3. Open http://localhost:8080, folders in the working directory will be displayed as collections. 🎉
  • 📝 Create a configuration.yaml in the working dir to configure the app
  • 🕵️‍♀️ Install exiftool and add it to PATH for better metadata support (esp. for video)
  • ⚪ Set the PHOTOFIELD_DATA_DIR environment variable to change the path where the app looks for the configuration.yaml and cache database

Configuration

You can configure the app via configuration.yaml.

The location of the file depends on the installation method, see Getting Started.

The following is a minimal configuration.yaml example, see defaults.yaml for all options.

collections:
  # Normal Album-type collection
  - name: Vacation Photos
    dirs:
      - /photo/vacation-photos

  # Timeline collection (similar to Google Photos)
  - name: My Timeline
    layout: timeline
    dirs:
      - /photo/myphotos
      - /exampleuser

  # Create collections from sub-directories based on their name
  - expand_subdirs: true
    expand_sort: desc
    dirs:
      - /photo

Development Setup

Prerequisites

  • Go - for the backend / API server
  • Node.js - for the frontend
  • just - to run common commands conveniently
  • watchexec - for auto-reloading the Go server
  • sh-like shell (e.g. sh, bash, busybox) - required by just
  • exiftool - for testing metadata extraction

Scoop (Windows): scoop install busybox just exiftool watchexec

Installation

  1. Clone the repo
    git clone https://github.com/smilyorg/photofield.git
  2. Install Go dependencies
    go get
  3. Install NPM packages
    cd ui
    npm install

Running

Run both the API server and the UI server in separate terminals. They are set up to work with each other by default with the API server running at port 8080 and the UI server on port 3000.

just is just as defined in the prerequisites.

API

  • just watch the source files and auto-reload the server using watchexec
  • or just run the server

UI

  • just ui to start a hot-reloading development server
  • or run from within the ui folder
    cd ui
    npm run dev

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

Distributed under the MIT License. See LICENSE for more information.

Acknowledgements