Skip to content

Repository files navigation

LUT Studio

LUT Studio

Create, edit and apply 3D LUTs to your photographs — with a comfortable before/after preview and real batch processing.

License: GPL v3 Python 3.10+ Qt for Python

🇬🇧 English · 🇮🇹 Italiano

LUT Studio main window

Every adjustment in LUT Studio is a pure per-pixel colour function, so the whole look bakes down into a single 3D LUT. What you see in the preview is exactly what gets exported — as .cube, .3dl or HALD PNG — and exactly what the batch writes to disk. The same LUT you build here works in Lightroom, Capture One, DaVinci Resolve, Premiere, Affinity Photo or OBS.

Features

  • Grading that becomes a LUT — white balance and exposure in scene-linear light, contrast, highlights/shadows/whites/blacks, HSL across eight colour ranges, ASC-CDL lift/gamma/gain wheels, split toning, black & white, and monotone RGB tone curves.
  • A preview you can actually judge — draggable split, side by side, A/B toggle, zoom to the cursor, pan, live histogram. Rendering happens off the UI thread, so the sliders stay responsive on 24-megapixel files.
  • LUT library — point it at your LUT packs: folders are scanned recursively and shown as a tree with counts and natural ordering (Look 2 before Look 10). Search, favourites, recents, and a thumbnail grid that renders your own photo through every LUT in the library.
  • A different look for every photo — assign the current look (LUT + adjustments + strength) to any selection, see it labelled in the queue, and batch-process only the assigned photos, each with its own LUT.
  • Crash-safe by design — assignments are written to disk the moment you make them, in JSON plus a human-readable CSV. Kill the app and your work is still there when it reopens.
  • Real batch — multi-process, RAM-aware, with format/quality/bit-depth, resizing, EXIF and ICC preservation, subfolder mirroring, progress, per-file log and cancellation.
  • Italian and English, following your system language, switchable from the View menu.
  • Command line for large jobs and automation.

Install

git clone https://github.com/IncludePetrol/LUTStudio.git
cd lut-studio
python3 -m pip install -r requirements.txt
python3 run.py

On macOS you can also double-click start.command, which installs anything missing and opens the app.

Installing as a package gives you the lutstudio and lutstudio-cli commands:

python3 -m pip install .

Requirements: Python 3.10+, NumPy, Pillow, PySide6.

Using it

┌────────────┬───────────────────────────────┬──────────────────┐
│ Photo      │  Before/after preview         │  Adjustments     │
│ queue      │  (split, side by side, A/B)   │  Curves          │
│ + looks    │  zoom, pan, histogram         │  Library · LUT   │
│            │                               │  Batch           │
└────────────┴───────────────────────────────┴──────────────────┘

You can drop photos, folders and .cube files straight onto the window.

Keyboard shortcuts

One key, no modifiers. They work whenever you are not typing in a text field; the classic combinations (Ctrl+O, Ctrl+S, …) keep working as alternates. Press H (or F1) in the app for the same list.

Looks
A assign the current look to the selection
X remove the assigned look
T assign to every photo in the queue
E load the assigned look back into the panels to edit it
M freeze the look as the base LUT
Z reset the adjustments
Library
double-click · Enter apply and assign the LUT to the photo
↑ ↓ try the LUTs one after another
Space favourite
C jump to the library search
V switch list / thumbnails
I add a LUT folder to the library
Batch
G process the assigned photos
R process every photo
File
O / D open photos / open folder
S / L save the photo / export the LUT
View
B / F / 1 before-after · fit · zoom 100%
, . previous / next photo
Alt+1…5 switch tool tab
Del remove the selected photos from the queue

Library

Add one or more folders (Add folder…, Ctrl+L, or drop them in). They are scanned recursively and shown folder by folder. .cube, .3dl and HALD PNG/TIFF are recognised; PNGs that are not real HALD tables — the preview images that ship with most LUT packs — are ignored automatically.

  • List — arrows ↑↓ walk through the LUTs with the preview updating as you go, so a whole pack takes seconds to review. The active LUT is bold.
  • Double-click (or Enter) on a LUT does not just preview it: it is applied and assigned to the selected photos in one gesture — the fastest way to go through a shoot.
  • Thumbnails — the entire library as a grid, each tile being your photo through that LUT, with its name and source folder underneath. Tiles render lazily as you scroll, so thousands of LUTs open instantly.

The chosen LUT becomes the base LUT: dose it with the strength slider, grade on top of it, and export the combined result.

One look per photo

Pick a LUT, adjust, then select photos in the queue and hit Assign look to selection (Ctrl+K, or right-click). A green dot with the look's name appears under the file name — strength included. Come back to that photo and the look is reloaded into the panels, ready to be tweaked and reassigned.

In the Batch tab, Assigned only (N) processes just those photos, each with its own LUT. Identical looks are baked once and shared between worker processes, so 300 photos with 5 looks cost the same as 300 photos with one.

Your work is saved to ~/.lutstudio/session.json (atomic write, with a .1 backup) on every change, alongside ~/.lutstudio/assignments.csv. Frozen looks — the ones with no source file — are stored as .cube in ~/.lutstudio/frozen_looks/. On the next launch the queue and every assignment come back on their own.

Command line

# apply a LUT to a folder, recursively, on 8 processes
lutstudio-cli apply ~/Photos/shoot -l look.cube -o ~/Photos/export -j 8

# apply a built-in preset, JPEG quality 92, long edge 2048 px
lutstudio-cli apply ~/Photos -p warm_film -o ~/export -f jpeg -q 92 --long-edge 2048

# bake a .cube out of a preset
lutstudio-cli bake -p teal_orange -s 65 -o teal.cube

# convert, resize or soften an existing LUT
lutstudio-cli convert look.cube look_soft.3dl --size 33 --strength 0.6

lutstudio-cli info *.cube
lutstudio-cli presets

(Without installing the package: python3 -m lutstudio.cli …)

Where things live

Everything the app keeps lives in ~/.lutstudio: library.json (your LUT folders and favourites), session.json + assignments.csv (queue and assigned looks), presets/ (your own presets), settings.json (language), crash.log. Point LUTSTUDIO_HOME somewhere else to move or sandbox it.

Performance and robustness

  • Photos are decoded at the resolution actually needed (JPEG draft mode): a thumbnail from a 24 MP file peaks at ~68 MB instead of ~965 MB.
  • Queue thumbnails are generated only for visible rows, three at a time, so hundreds of large photos keep memory flat.
  • Batch worker count adapts to available RAM as well as core count.
  • LUT application is branch-free tetrahedral interpolation, working in place: 24 megapixels in ~2.6 s.
  • JPEG export above 12 Mpx is written baseline instead of progressive, because progressive forces libjpeg to hold the whole file in a single buffer and fails on large, detailed photos.
  • Unexpected errors do not close the app: they are logged to ~/.lutstudio/crash.log (which also captures native crashes) and reported once.

Project layout

run.py                  GUI launcher
selftest.py             engine self-test
start.command           macOS launcher
tools/make_icon.py      regenerates the app icon
lutstudio/
  cli.py                command line interface
  core/
    lut.py              LUT3D: identity, .cube/.3dl/HALD, interpolation, mixing
    grade.py            grading pipeline and LUT baking
    curves.py           monotone curves (Fritsch–Carlson)
    color.py            sRGB ↔ linear, HSL, white balance
    imageio.py          image read/write, histogram, resizing
    raw16.py            16-bit PNG/TIFF writers
    batch.py            multi-process batch engine
    look.py             a complete look, assignable to a photo
    session.py          automatic session persistence
    library.py          LUT folder library
    presets.py          built-in and personal presets
    i18n.py             Italian/English interface strings
  gui/                  main window, preview, panels, curve editor, library

Development

python3 selftest.py          # 27 checks on the engine, no GUI needed
python3 -m pyflakes lutstudio
python3 tools/make_icon.py   # regenerate assets/icon*

The self-test covers interpolation accuracy against direct grading, .cube and .3dl round-trips, curve monotonicity, batch behaviour across processes, per-photo looks and session persistence. It runs on every push through GitHub Actions.

Credits

Created by Andrea Parolini.

Built with Python, PySide6, NumPy and Pillow.

Copyright © 2026 Andrea Parolini.

LUT Studio is free software, released under the GNU General Public License v3.0 or later. You may use, study, modify and share it; if you distribute it — modified or not — you must pass on the same freedoms and provide the source code under the same licence. The program comes with absolutely no warranty.

Attribution is required. Under section 7(b) of the GPL, every redistributed or modified version must keep the credit "LUT Studio — Andrea Parolini" and the copyright notice visible: in the About window, in the documentation, and in the NOTICE file that must travel with the program. Modified versions must also say clearly that they have been modified.

About

Create, edit and batch-apply 3D LUTs to your photos, with a before/after preview — by Andrea Parolini

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages