andreavolpato/spektrafilm
Media & DesignTurns camera RAW or linear images into physically based spectral film, print, and scan simulations with an interactive desktop GUI and LUT export.
What it does
spektrafilm is a spectral, physically based simulator of the analog color photography pipeline. It takes a camera RAW file or an already prepared linear image, exposes it onto a virtual negative using film-stock data from manufacturer datasheets, develops the dyes with characteristic curves and coupler effects, projects the negative through a virtual color enlarger onto print paper, and finally scans the virtual print. The goal is not a generic "film look" preset but a model grounded in measured data that predicts how stocks, couplers, grain, halation, and enlarger settings shape the result.
It is aimed at photographers, color scientists, and tool developers who want to experiment with film renderings or build on the model. The Python repository is the reference implementation; the README also points to faster Vulkan, Rust, OFX, and ART-based spin-offs. The core is split into three packages: the runtime pipeline (linear in, linear out), a Qt + napari desktop GUI, and an LUT creator that bakes .cube / .3dl / Hald-CLUT bundles with optional OCIO configs.
Quick start
Python 3.13 is required, since newer versions are not compatible. The simplest route is uv, which installs and launches the GUI in one command:
uvx --python 3.13 --from git+https://github.com/andreavolpato/spektrafilm.git spektrafilm
Alternatively, install permanently so the spektrafilm command is available:
uv tool install --python 3.13 git+https://github.com/andreavolpato/spektrafilm.git
spektrafilm
A pip + virtual environment workflow also works and includes the GUI and LUT creator by default:
conda create -n spektrafilm python=3.13
conda activate spektrafilm
git clone https://github.com/andreavolpato/spektrafilm.git
cd spektrafilm
pip install -e .
spektrafilm
Once the napari window opens, import a RAW file in the import raw section (choose white balance, then select file), pick a film and print profile such as kodak_portra_400 and kodak_portra_endura, adjust exposure, and press scan_film then PREVIEW to see a virtual scan. Full-resolution output uses SCAN instead of preview. Controls have tooltips; a GUI demo video shows the workflow.
To use the Python API directly:
from spektrafilm import create_params, simulate
params = create_params(
film_profile="kodak_portra_400",
print_profile="kodak_portra_endura",
)
result = simulate(image, params)
For LUT baking, the spektrafilm-lut CLI accepts canonical color-space names or short tags:
spektrafilm-lut build \
--film kodak_portra_400 \
--print kodak_portra_endura \
--input vlog --output srgb \
--topology 1lut --resolution 33 \
--qa --ocio-config \
--out ./build/lut_bundles/
Available profiles and color spaces can be listed with spektrafilm-lut list film|print|input|output|target.
Usage constraints
- Slow full-resolution rendering. The author reports about 10 seconds for 6 MP images on a laptop; use PREVIEW while tuning and SCAN for finals.
- Color management caveat. napari is not color-managed. The recommended setup is screen/OS profile set to sRGB with the simulation output in sRGB; Windows may apply the display profile and indicate this in the status bar.
- Input format. The GUI's file loader accepts 16-bit and 32-bit images (PNG, TIFF, EXR known to work) and expects scene-referred linear data, ideally in a wide-gamut space such as linear Rec2020 or linear ProPhoto RGB. Manually developed images can come from darktable with non-linear mappings disabled.
- Experimental state. The project is in rapid development with many undocumented or little-documented GUI controls, and Fujifilm data are noted as less self-consistent than Kodak data.
- Licensing. Source code is GPL-3.0, so derivative work must also be open source under the same terms; JSON profiles and LUTs are CC BY-SA 4.0, and LUT files carry a separate "commercial use, free share, no resale" license.
- Repository size. A 2026/05/28 history cleanup reduced the repo from about 140 MB to 45 MB, so old clones should be recloned.
HotRepo's take
On the Python daily list for 2026-11-01, spektrafilm recorded 142 new stars in a day and reached position 11, a notable single-day showing for a niche color-science tool. That snapshot also puts the repository at 1451 stars and 188 forks, and an HN thread from 2026-04-14 drew limited discussion (15 points, 1 comment) pointing readers to the dev branch. The wider ecosystem hinted at in the README — Vulkan, Rust, OFX, and ART integrations by other developers — together with 188 forks suggests the model is being reused as a reference rather than only run as an app, which fits its stated role as the canonical implementation others port.
Written by AI from the project's README, updated . The project's own docs are the source of truth.