src/main/resources/userguide/credits.md now lists every shipped library with its license (read from the dependencies' POMs), the recognition models and the map and place data. CreditsView, opened from the ? in Settings, renders it through the new MarkdownPage helper (per-language loading, links opened in the browser), which the search help popup now shares, and the release's distrib step copies it to distrib/CREDITS.md in the same commit as the release note. MarkdownToBBCode learns [text](url) links, inside bold too. URLs are quoted in the generated BBCode: AtlantaFX's parser reads a tag ending in "/]" as self-closing, so a URL with a trailing slash broke the whole page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011xpLSeYKKHX6o16jzYLgZv
7.2 KiB
Pholio
Pholio is a desktop application for managing large photo and video libraries, built for volume and speed.
- Libraries — point Pholio at one or more folders; it indexes every photo and video into its own embedded database, one per library, and keeps it in sync as files change.
- Gallery — a justified, date-grouped grid that stays fluid on tens of thousands of files, with a full-screen photo view and an info panel for the selected file.
- Metadata — reads EXIF, IPTC and XMP (RAW, HEIF and video included), edits capture date, location and rating, and writes them back to the file itself.
- Places — offline reverse geocoding from a bundled GeoNames dataset, plus optional online place search (LocationIQ).
- People — local face and animal detection and clustering (ONNX Runtime, nothing leaves the machine); naming a person makes their photos searchable.
- Search — free text, rating (
r:4+), people (p:Alice) and folder (path:Holidays/2024) filters, combined freely — see the in-app guide (the?next to the search bar) orsrc/main/resources/userguide. - Command line — the same binary runs headless:
pholio scan <dir>reports the media files a folder holds.
Built with Java 26, JavaFX (AtlantaFX, GemsFX, Ikonli), Spring Boot, H2, PicoCLI and metadata-extractor.
Build and run
Requirements: a JDK 26 that bundles JavaFX (e.g. Azul Zulu FX 26). Maven comes with the wrapper.
./mvnw verify # compile, test, build target/pholio.jar
java -jar target/pholio.jar --ui # desktop interface
java -jar target/pholio.jar scan ~/Pictures [-R] # headless scan; -R: do not recurse
java -jar target/pholio.jar -V # version
java -jar target/pholio.jar # usage, same as --help
Pholio runs headless by default: only --ui opens the window, so every launcher meant to show one (IDE run
configuration, installers) passes it. Any argument Pholio does not recognise is read as a command.
Development
JVM options (-D…)
| Option | Default | Effect |
|---|---|---|
--enable-native-access=javafx.graphics,ALL-UNNAMED |
— | Not a property, but recommended: silences the restricted-method warnings from JavaFX, JNA and the macOS process naming. |
-Dpholio.home=<dir> |
OS user dirs | Puts configuration, data (libraries) and cache under one root — keeps a test run out of your real profile. |
-Dpholio.skipTheme=true |
false |
Starts without the AtlantaFX theme, on JavaFX's default styling (to tell a theme issue from a layout one). |
-Dpholio.modalBackend=dialogPane |
stage |
Shows dialogs in GemsFX's embedded DialogPane instead of a separate window. |
-Djavafx.enablePreview=true |
set by the app | Required for the JavaFX HeaderBar preview API; GuiBootstrap sets it unless you pass a value. |
-Dprism.dirtyopts=false |
set by the app | Works around a stale-paint bug in Prism; GuiBootstrap sets it unless you pass a value. |
Application settings (--pholio.…= arguments)
Spring Boot settings from application.yaml, overridable on the command line (they bypass PicoCLI, so they
never read as a command):
| Setting | Default | Effect |
|---|---|---|
--pholio.dev-tools.enabled= |
true |
F12 opens the DevToolsFX scene-graph inspector. |
--pholio.library.routing.enabled= |
true |
Routes the database to the library picked in the header; false pins spring.datasource.url. |
--pholio.pools.cpu= |
0 |
Threads for decoding work (thumbnails, hashes); 0 = cores − 1. |
--pholio.pools.scheduler= |
2 |
Scheduler threads. |
--pholio.window.default-width= / default-height= |
1440 / 900 |
First-run window size. |
--logging.level.org.icroco.pholio= |
DEBUG |
Log level of Pholio's own code. |
What makes the jar big
target/pholio.jar is ~223 MB, 89 libraries. Almost all of it is recognition: the application's own code is
under 1 MB.
| Size (in the jar) | Entry | Why |
|---|---|---|
| 130.5 MB | onnxruntime-1.21.1.jar |
ONNX Runtime with native libraries for 5 platforms (~590 MB unpacked, win-x64 alone 351 MB). The installers keep only their own platform's — see below. |
| 34.2 MB | models/recognition/face_recognition_sface_2021dec.onnx |
Face embedding model (SFace). |
| 10.2 MB | geodata/cities1000.txt.gz |
GeoNames seed for offline reverse geocoding, imported into H2 on first run. |
| 4.4 MB | byte-buddy |
Runtime agent behind @FxThread. |
| 3.2 MB | models/recognition/yolox_nano.onnx |
Animal detection model. |
| 3.0 MB | gemsfx |
UI controls. |
| 2.6 MB | h2 |
Embedded database. |
| ≤ 2 MB each | Spring, Jackson, JNA, AtlantaFX themes, … | The remaining ~30 MB. |
Deliberately left out of the jar (pom.xml): Lombok and Jilt (compile-time only), the OpenJFX jars (every
target runtime already has JavaFX as modules), and the JUnit/AssertJ that devtoolsfx wrongly declares at
compile scope.
The native installers go further (distrib/packaging/common.sh): only the target platform's ONNX Runtime
natives (130 MB → ~24 MB for macOS arm64) and a jlink'ed runtime (~64 MB) — the macOS arm64 .dmg is ~157 MB.
To re-measure: unzip -v target/pholio.jar | sort -k3 -n -r | head -20 (third column: compressed size).
Credits
src/main/resources/userguide/credits.md is the single list of credits — shipped libraries with their
licenses, recognition models, map and place data. The application shows it from the ? in Settings
(CreditsView), and each release copies it to distrib/CREDITS.md. Add a library or data source there when
you add one to the application.
Useful scripts
python3 tools/icons/make-macos-icon.py— regenerates the macOS icon,icon.pngandpholio.icnsfromsrc/main/resources/images/spo-1024x1024.png.python3 tools/demo/fetch-commons-photos.py <dir> [--quality] [--places Paris Kyoto …] [--per-place N]— downloads a demo library for screenshots from Wikimedia Commons: freely licensed JPEG originals whose own EXIF has a capture date and GPS, one folder per city, with aCREDITS.md(CC BY / BY-SA require the credit wherever the photos are shown).--qualitykeeps only Commons' Quality/Featured pictures — nicer, fewer, slower.--helpfor every option.
Release
./mvnw -Prelease validate
Needs a clean working tree (or -Drelease.allowDirty=true) and a logged-in GitHub CLI (gh auth login).
In order, it:
- bumps the version to
YYYY.M.N— same month as the current version:N + 1, otherwise build 0 of the current month; - runs a fresh
./mvnw verify; - writes
distrib/release_note/release-note-<version>.mdfrom the Conventional Commits since the previous release (grouped by type, then scope); - creates GitHub release
v<version>in Imag-In/Pholio with the jar, its SHA-256 and the release note; - commits
pom.xmland tagsv<version>locally; - commits the release note in
distrib/and pushes it.
The source repository itself is never pushed to GitHub: Imag-In/Pholio only receives release assets and
the distrib/ worktree (an orphan branch), and a local pre-push hook enforces it. See AGENTS.md for the
details, and keep commit messages in the Conventional Commits format so they reach the release note.