惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Last Week in AI
Last Week in AI
D
DataBreaches.Net
腾讯CDC
Recent Announcements
Recent Announcements
有赞技术团队
有赞技术团队
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
罗磊的独立博客
月光博客
月光博客
MyScale Blog
MyScale Blog
U
Unit 42
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
N
Netflix TechBlog - Medium
G
Google Developers Blog
博客园 - 【当耐特】
D
Docker
I
InfoQ
雷峰网
雷峰网

Hacker News: Show HN

PurrrrrFocus: Pomodoro Timer App - App Store Workflow Engine — Multi-Step Orchestration for Bun RapidPhoto: Pro Photo Editor App - App Store GitHub - DheerG/swarms: Achieve extraordinary results with claude code across a variety of tasks SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads Show HN: VCoding – A 5 MB native Windows IDE with no dynamic dependencies Show HN: LLMs don't hallucinate because they're bad at math, it's the format GitHub - Agent-FM/agentfm-core: AgentFM is a peer-to-peer network that turns everyday computers into a decentralized AI supercomputer. AgentFM lets you run massive AI workloads directly across a global mesh of idle CPUs and GPUs. Show HN: Tracking Top US Science Olympiad Alumni over Last 25 Years GitHub - Potarix/agent-hub: One place to talk to all your agents Show HN: Runtime security for AI agents(injection,tool abuse, data exfiltration) GitHub - dubeyKartikay/lazyspotify: Terminal Spotify client for macOS and Linux GitHub - the-banana-tool/king-louie: Easy to use GUI Personal AI Assistant. Win/Linux/Mac. Show HN I made my vacation rental bookable by AI agents–no Airbnb, 0% commission GitHub - basteez/jsf-autoreload: maven plugin to enable hot reload on jsf projects uvm32/hosts/host-gdbstub at main · ringtailsoftware/uvm32 GitHub - labsai/EDDI: Config-driven engine that turns JSON into production-grade AI agents. Multi-agent orchestration, 12+ LLM providers, MCP/A2A protocols, RAG, persistent memory, and enterprise compliance (EU AI Act, GDPR, HIPAA). Built on Quarkus. GitHub - glitchnsec/fortyone-oss: AI Executive Assistant Platform Quickstart | Alien GitHub - muxshed/shed: One stream in, or many. Every destination, simultaneously. No cloud middleman, no per-channel fees, no limits. GitHub - ocrbase-hq/ocrbase: 📄 PDF/IMG ->.MD/JSON Document OCR API for PaddleOCR and GLMOCR. Self-hostable. GitHub - impactjo/home-memory: MCP server that lets your AI assistant remember everything about your home. GitHub - Sets88/dbcls: DbCls is a powerful terminal database client that supports various databases GitHub - neptun2000/heor-agent-mcp GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh RollQuation: Math Puzzles - Apps on Google Play GitHub - dropbox/witchcraft Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis GitHub - opentalon/opentalon: OpenTalon is an open-source platform built from the ground up in Go as a robust alternative to OpenClaw LinkedIn™ 职位抓取工具 - Chrome 应用商店
GitHub - alfanick/mini-film: Batch processor of camera ra...
alfanick · 2026-06-17 · via Hacker News: Show HN

mini-film is a complete photo-to-review-to-publish workflow for photographers who want film-emulation output without opening Lightroom. It watches an inbox of RAW, JPEG, and HEIC files, develops RAWs through RawTherapee, applies user-supplied film profiles and grain to RAW outputs, serves a live review UI, records ratings/tags/notes, and publishes the final selection with metadata preserved.

The fastest way in is the desktop app:

With no command, mini-film opens the native app wizard for the usual daemon/review settings, profile selection, Nikon WTU ingest, lens corrections, output folders, and publishing defaults. The app remembers the last successful setup, starts the same daemon pipeline used by the CLI, waits for the embedded review server, and then opens the review UI in a webview. Terminal output is still kept when launched from a shell, so long-running processing stays inspectable. mini-film app remains available as the explicit command form.

For scripted use, every part of the workflow is still available as CLI commands: apply, batch, daemon, sampler, pp3, info, nikon, and update.

Screenshots

Main review view:

mini-film main review view

Publishing workflow:

mini-film publishing workflow

Available shortcuts:

mini-film shortcuts overlay

Top Features

  • Single-binary desktop workflow: mini-film provides a Tauri launcher with native directory pickers, a structured profile tree, saved options, network sharing toggle, Nikon WTU IP input, and system light/dark theme.
  • Live review and publish workflow: run daemon on an inbox folder, open the browser UI, review new pictures as they arrive, rate/tag/label them in multiple passes, compare profile variants, and publish the final selection with live job progress. The review workflow is optimized for fast keyboard operation, while still supporting mouse, touch, and tablet use.
  • Mixed RAW and processed-file input: batch, daemon, review, and publish can take RAW files plus existing JPEG/HEIC files. RAWs get profiles and adjustment sliders; JPEG/HEIC inputs keep their existing look and expose rating, labels, tags, notes, crop, and rotation only.
  • Optional Codex review assist: let Codex analyze small embedded RAW previews after rendering finishes and fill tags, notes, or initial ratings while the live review UI shows the same queued/processing status indicators.
  • Film emulation from user-supplied profiles: apply XMP emulation presets, Hald CLUT PNGs, or RawTherapee .pp3 files; convert Adobe Camera Raw / Lightroom crs:RGBTable profile XMPs into cached 16-bit Hald PNGs.
  • Nikon WTU ingest: pair with Nikon Connect-to-PC / Wireless Transmitter Utility mode over built-in camera Wi-Fi and feed transferred RAWs directly into the daemon inbox.
  • Batch, sampler, and gallery output: process whole folders, render profile sampler sheets, and generate modern static HTML galleries.
  • RAW pipeline extras: deterministic film grain, optional high-ISO color denoise, optional RawTherapee lens corrections, metadata copyback with exiftool, 8-bit JPEG output, and 16-bit Zip-compressed TIFF output.

Profile Library

mini-film does not include film profiles or emulations. It works with XMP, Hald, and PP3 profiles already present on disk, including profiles created by the user or obtained from commercial film-emulation products.

For XMP preset libraries, point --profiles-root at a directory with:

profiles/     # internal RGBTable profile XMPs
emulations/   # user-facing emulation preset XMPs

Quick Start

Apply one profile to one RAW:

mini-film apply input.RAW \
  --profile 'Classic Film' \
  --profiles-root /path/to/profile-library \
  --output output.jpg

Batch-process a folder, accepting RAW plus JPEG/HEIC inputs by default:

mini-film batch /path/to/photos /path/to/output \
  --profile 'Classic Film' \
  --profiles-root /path/to/profile-library \
  --long-edge 3840 \
  --progressive-jpeg

Use --input-raw-only or --input-jpg-only when a mixed input folder should be filtered before processing. JPEG and HEIC are treated as the same processed-file group for these filters.

In the default mixed mode, a JPEG/HEIC with the same normalized stem in the same folder as a RAW is treated as that RAW's straight-out-of-camera sidecar instead of a separate picture. A trailing dash-number suffix is ignored for this match, so DSC_8313-1.jpg pairs with DSC_8313-2.dng. The review UI shows it as an unchecked straight out of camera profile thumbnail; if selected for publish, its output uses the -sooc suffix.

Image files that are symlinks inside the input folder are treated like normal input files, including review and publish rerenders.

Run the live review workflow:

mini-film daemon /path/to/inbox /path/to/output \
  --profile 'Classic Film' \
  --profile 'Soft Fade' \
  --profiles-root /path/to/profile-library \
  --review-address 0.0.0.0:8090

Then open http://localhost:8090, review pictures as they are processed, and use the publish wizard to export the final album.

Run the desktop wizard instead of writing the daemon command manually:

The app wizard defaults to ~/Pictures/Scratch/Inbox for input, ~/Pictures/mini-film for output, and MINI_FILM_PROFILES_ROOT or the selected profiles root for profile lookup. It remembers the last successful setup in ~/.cache/mini-film/app-settings.json.

Use Nikon WTU ingest with the same daemon:

mini-film daemon /path/to/inbox /path/to/output \
  --profile 'Classic Film' \
  --profiles-root /path/to/profile-library \
  --review-address 0.0.0.0:8090 \
  --nikon-wtu 192.168.1.50

Build

The default build includes the Tauri desktop app so cargo run --release opens the app from the normal binary. On Linux this requires the WebKitGTK development packages used by Tauri. On Debian/Ubuntu/Linux Mint:

sudo apt-get install \
  libwebkit2gtk-4.1-dev \
  libjavascriptcoregtk-4.1-dev \
  libsoup-3.0-dev \
  libgtk-3-dev \
  libayatana-appindicator3-dev \
  librsvg2-dev \
  patchelf

To build the command-line binary without desktop GUI dependencies:

cargo build --release --no-default-features

GitHub releases publish both CLI artifacts and GUI artifacts. GUI artifact names end in -gui before the platform extension, and GUI builds update from matching -gui release assets.

Required external dependencies at startup for image-generation commands:

  • rawtherapee-cli
  • convert (ImageMagick/GraphicsMagick)
  • exiftool
  • codex only when daemon review analysis is enabled with --codex

The update command also requires curl for downloading the Lensfun database.

Coverage

Generate LCOV coverage locally (requires cargo-llvm-cov):

cargo install --locked cargo-llvm-cov
./scripts/coverage.sh

The script writes:

target/coverage/lcov.info

CI runs the same coverage step on every push/PR and uploads coverage-lcov as an artifact.

Update

Use update to manually refresh the mini-film executable from https://github.com/alfanick/mini-film/releases and rebuild/update the local Lensfun profile database in ~/.cache/mini-film/lensfun.

The command also mirrors Lensfun DB files into the platform default location used by RawTherapee.

Update behavior is not automatic. Run it explicitly when a new release is expected or before long sessions. The binary refresh still requires this crate to be built with --features github-update; the Lensfun database refresh does not.

Convert XMP Profiles To Hald

Convert one profile XMP:

cargo run --release -- hald \
  '/path/to/profile-library/profiles/Kodak Portra 400 normalised profile.xmp' \
  -o '../hald/Kodak Portra 400 normalised.hald.png' \
  --overwrite

Convert all profile XMPs under the parent directory:

cargo run --release -- hald /path/to/profile-library/profiles --overwrite

Ordinary emulation preset XMPs usually only reference a profile UUID and do not contain the table payload; hald skips those in directory mode.

When -o/--output is omitted, hald writes generated Hald PNGs under $HOME/.cache/mini-film/hald. Hald PNGs contain only the decoded RGBTable lookup. Profile XMPs that include extra Camera Raw settings print adjustments=pp3 or sharpening=pp3; those settings are handled through generated RawTherapee profiles during apply, batch, and sampler.

Apply A Complete Film Recipe

Use a Lightroom emulation XMP that references an internal profile and defines grain:

cargo run --release -- apply input.RAW \
  --profile '/path/to/profile-library/emulations/Kodak Portra 400 warm grainy.xmp' \
  --profiles-root /path/to/profile-library \
  -o output.tif

If --profile is an emulation name, set --profiles-root to a folder that contains emulations/ and profiles/:

cargo run -- apply \
  --output /home/alfanick/test.jpg \
  --profile 'Agfa Scala 200 + grainy' \
  --profiles-root /path/to/profile-library \
  /home/alfanick/Pictures/Lightroom/2026/05/03/DSC_1812-10.dng

output.tif / output.tiff is exported as 16-bit Zip-compressed TIFF.

cargo run --release -- apply input.RAW \
  --profile '/path/to/profile-library/emulations/Kodak Portra 400 warm grainy.xmp' \
  --profiles-root /path/to/profile-library \
  -o output.jpg

output.jpg / output.jpeg is exported as 8-bit JPEG.

Use a human-edited RawTherapee profile directly:

cargo run --release -- apply input.RAW \
  --profile edited-profile.pp3 \
  -o output.jpg

When --profile points at a .pp3, mini-film passes that PP3 directly to RawTherapee. If the PP3 contains a [Film Simulation] section, RawTherapee applies its referenced Hald during RAW development. PP3-only profiles do not carry mini-film grain metadata.

Output metadata behavior for apply, batch, daemon, and sampler:

  • source EXIF/IPTC fields are copied from the input RAW to the output file using exiftool (unless --strip-metadata is set)
  • generated outputs are annotated with Adobe-style XMP Camera Raw settings (XMP-crs) for resolved mini-film profile adjustments, sharpening, HSL, calibration, tone-curve, and grain values where mini-film has real structured data for the render
  • the XMP packet also records mini-film as the creator/converter and adds a high-level xmpMM history entry with the raw file, profile, linked profile, Hald or PP3 source, grain state, and grain seed
  • an EXIF comment is written as
    mini-film <version> usage=<command> profile=<profile-or-emulation> or profile=none when no profile was configured

For JPEG/HEIC inputs, source metadata is copied from the compressed source and mini-film only adds its basic version/comment marker and review/publish metadata. Camera Raw Settings edit history is reserved for RAW-generated outputs.

Batch Apply

Process every supported RAW file (.dng, .nef, .cr2, .cr3, .arw, .raf, .orf, .rw2, etc.) plus JPEG/HEIC files (.jpg, .jpeg, .heic, .heif) under an input directory and write JPGs or 16-bit TIFFs under an output directory:

cargo run --release -- batch \
  /home/alfanick/Pictures/Lightroom/2026/05/03 \
  /home/alfanick/batch-output \
  --profile 'Agfa Scala 200 + grainy' \
  --profiles-root /path/to/profile-library \
  --output-format jpg \
  --jobs 8

The output directory is created if it does not exist. Nested input folders are preserved, and each input uses the same relative path with a .jpg extension by default. Use --output-format tiff to write .tif files through the 16-bit Zip-compressed TIFF path. JPEG/HEIC inputs are converted directly with resize/crop/rotation and metadata copyback; RAW-only profiles, grain, denoise, and lens corrections are skipped for those files.

By default, batch processes half of the detected CPU threads at once. On a 16-thread CPU that means 8 files in parallel. Override it with --jobs N when tuning for a different machine, output format, or memory budget.

batch shows two progress bars:

  • total batch progress across files
  • current file progress across RAW decode/Hald/grain or compressed-file export steps

Batch Gallery

Pass --gallery to generate a gallery HTML from all successful batch outputs:

mini-film batch \
  /home/alfanick/Pictures/Lightroom/2026/05/03 \
  /home/alfanick/batch-output \
  --profile 'Agfa Scala 200 + grainy' \
  --gallery modern \
  --gallery-columns 4 \
  --gallery-thumbnail-long-edge 1024

--gallery accepts one of modern, soft, compact, hero, phone, or all.

Template intent:

  • modern: masonry-like variable-cards layout with generous spacing and hero-like first-look cadence
  • soft: editorial light look with warm spacing and caption emphasis
  • compact: dense compact grid for quick scanning
  • hero: story-focused layout with a large leading tile and balanced follow-ups
  • phone: iOS/iPadOS photos style, dense square tiles
  • all: render all five templates

Batch gallery options are folder-friendly and reuse the existing batch output tree (including subdirectories). For a single template, the gallery is written as <output>/index.html and uses <output>/thumbnails/.

--gallery all renders all five gallery templates into:

  • <output>/modern/index.html
  • <output>/soft/index.html
  • <output>/compact/index.html
  • <output>/hero/index.html
  • <output>/phone/index.html

The template run reuses one shared thumbnail cache at <output>/.mini-film-gallery-thumbnails/ so switching layouts does not reprocess or regenerate thumbnails.

Daemon

Run a long-lived watcher that applies optional profiles whenever new files arrive in an input folder. If no --profile is provided, each RAW is developed once with RawTherapee defaults. JPEG/HEIC inputs are converted directly without profiles.

mini-film daemon \
  /home/alfanick/Pictures/Lightroom/inbox \
  /home/alfanick/Pictures/mini-film-output \
  --profile 'Agfa Scala 200 + grainy' \
  --profile 'Portra 400' \
  --profiles-root /path/to/profile-library \
  --debounce-seconds 1 \
  --jobs 8 \
  --output-format jpg

The command validates configured profiles on startup, so mistyped --profile values fail immediately. It watches the input directory recursively, waits for the file to be reported as completed by the watcher (or a short fallback window when that signal is not available), and writes each result into:

<raw relative structure>/<profile stem>/<raw stem>.<ext>

Without --profile, daemon output uses the raw-relative structure directly:

<raw relative structure>/<raw stem>.<ext>

For example, /in/2026/05/03/DSC_1864-14.dng with profiles Foil and Classic becomes:

  • /out/2026/05/03/Foil/DSC_1864-14.jpg
  • /out/2026/05/03/Classic/DSC_1864-14.jpg

If profile resolution fails for any selector, startup stops with a clear error.

daemon processes input files in parallel and defaults to half the available CPU threads unless --jobs is set.

Live Review

Add --review-address to expose a browser-based review UI while the daemon is running:

mini-film daemon \
  /home/alfanick/Pictures/Lightroom/inbox \
  /home/alfanick/Pictures/mini-film-output \
  --profile 'Classic Film' \
  --profile 'Soft Fade' \
  --profiles-root /path/to/profile-library \
  --review-address 0.0.0.0:8090 \
  --gallery modern

The review server assets are compiled into the binary, so a release executable does not need HTML/CSS/JS files next to it. The UI is live: the daemon records new RAW and JPEG/HEIC files immediately, extracts an embedded camera preview when available, then updates the browser over server-sent events as each render moves from queued to processing to done. When no profiles are configured, the review UI shows the developed RawTherapee-default output without a profile rail. JPEG/HEIC inputs also hide the profile rail because they are already processed. The first --profile is the default selected look for RAW files when profiles are configured. All configured profile variants are selected for publish by default; use the checkbox on each profile thumbnail to exclude or re-include a variant while reviewing.

Multiple browsers can use the review page at the same time. The current picture and minimum rating filter are server-owned shared state, so every browser shows the same review position. Navigation, filter changes, keyboard ratings, and rating-button clicks update that shared state and are replicated to every connected browser through the server-sent event stream. At the end of a pass, the shared filter moves to the next rating level.

Review data and the shared browser position are persisted in <output>/mini-film-review.json. A human-readable audit trail of review, render, and publish state changes is appended to <output>/history.txt. Together those files make it possible to restart the daemon, reopen the browser, and continue the multi-pass culling flow where it stopped. A typical pass is to rate everything 0 or 1, filter to >= 1, rate the survivors higher, and repeat until the final subset is ready.

The review workflow is optimized for keyboard operation. Press ? in the browser UI to show the shortcuts overlay. 1-5 rates and advances, arrow up/down changes the rating and advances, left/right or h/l navigates without rating, PageUp/PageDown cycles the profile preview for the current picture, and Space includes or skips the selected profile for publish. Double-click or double-tap a profile thumbnail to publish only that profile and exclude the others. 6, 7, 8, 9, and 0 toggle red, yellow, green, blue, and purple labels without advancing; r, y, g, b, and p provide the same mnemonic label toggles. c copies the current retouch slider adjustments, and v pastes them onto another picture.

The review UI stores rating, label, tags, notes, active preview profile, and the set of profile variants selected for publish. RAW inputs support per-picture retouch controls for exposure, highlights, shadows, whites, blacks, relative color temperature, clarity, rotation, and crop. JPEG/HEIC inputs support crop and rotation only. The browser applies a fast draft preview while edits are being made, then queues a high-quality mini-film render and swaps in the finished output when it is ready. Crop and rotation are persisted with the review state and are used by publish rerenders.

Optional Codex analysis can run after each RAW has a camera preview and its configured profile renders have finished:

mini-film daemon \
  /path/to/inbox \
  /path/to/output \
  --profile 'Classic Film' \
  --profiles-root /path/to/profile-library \
  --review-address 0.0.0.0:8090 \
  --codex tags,note

--codex without a value defaults to tags only. Explicit values are comma-separated: tags, note, rating, or all. Tags are normalized into the same tag field used by manual review. Notes are one-sentence descriptions. Ratings use a conservative 0 to 3 scale where 0 means technically unusable, 1 technically correct, 2 interesting, and 3 truly good. Manual edits always win: once a user changes tags, notes, or rating, later Codex results do not overwrite that field. Camera ratings imported from RAW metadata, including Nikon in-camera star ratings exposed by ExifTool as Rating or Nikon/XMP rating tags, are protected from Codex rating updates too. While analysis is queued or running, the existing review sidebar status dot/text and the main profile status line show the Codex state.

The default model is gpt-5.4-mini; override it or the binary path with:

--codex-model gpt-5.4-mini
--codex-binary codex
--codex-timeout 45

Publishing opens a wizard that acts as a browser frontend for a spawned mini-film review-publish job. The wizard can filter by rating, color label, and tags; choose a relative album folder inside the daemon output directory; select JPG/TIFF output, original size or resize options, JPEG quality/subsampling/progressive mode, and an optional gallery template. Publish jobs run in parallel with the daemon job count, which defaults to half the available CPU threads, and stream live progress back to every open review browser.

The default publish settings match the daemon render settings, so publishing uses hardlinks to the already-reviewed outputs when possible and falls back to symlinks if hardlinks are not available. If output settings differ, mini-film rerenders the selected pictures from the original RAW, JPEG, or HEIC inputs through the normal apply pipeline before building the gallery.

Published outputs are flat under the chosen album folder:

<output>/<album>/<raw stem>.<ext>
<output>/<album>/<raw stem>-<profile stem>.<ext>

With no daemon --profile, published files use <raw stem>.<ext>. Otherwise, the first daemon --profile is treated as the default profile and does not add a profile suffix. Additional selected profiles add -<profile stem>. If a gallery template is chosen in the wizard, publish renders an index.html gallery in the album folder using the same templates as batch. Supported templates are modern, soft, compact, hero, phone, and all.

Published JPGs are annotated with review metadata through exiftool: rating, label, tags, published profile, notes, and a mini-film version/comment marker. The source RAW metadata and mini-film XMP edit metadata copied during normal output generation are preserved unless --strip-metadata is used.

The same publish operation can be run directly from the CLI:

mini-film review-publish \
  --state /home/alfanick/Pictures/mini-film-output/mini-film-review.json \
  --input-root /home/alfanick/Pictures/Lightroom/inbox \
  --output-root /home/alfanick/Pictures/mini-film-output \
  --album published/final \
  --min-rating 3 \
  --label green \
  --gallery modern

Daemon can also ingest files from a Nikon camera configured for Connect-to-PC / Wireless Transmitter Utility style transfer. Start the camera's connection wizard, make sure the computer can reach the camera address, then point mini-film at that address. mini-film drives the Nikon pairing/auth step, downloads RAWs into the watched inbox, and processes them with the normal daemon queue:

mini-film daemon \
  /home/alfanick/Pictures/Lightroom/inbox \
  /home/alfanick/Pictures/mini-film-output \
  --profile 'Classic Film' \
  --profiles-root /path/to/profile-library \
  --nikon-wtu 192.168.1.50

The Nikon WTU receiver is native PTP/IP over TCP port 15740; it does not use external camera-control tools. During first-time setup it requests the camera's pairing code, accepts the wizard, completes pairing, reconnects, and then waits for transferred RAW objects. Non-RAW transfer objects are consumed silently so they do not block the camera's transfer queue. mini-film persists a stable initiator GUID in $HOME/.cache/mini-film/nikon-wtu-guid unless --nikon-wtu-guid is provided, and records successful camera pairings in $HOME/.cache/mini-film/nikon-wtu-pairings.json. Later daemon runs reuse the cached camera/name/GUID identity and go straight to transfer mode. If a camera was previously paired to a different identity, remove that pairing on the camera or reuse the same computer name/GUID with --nikon-wtu-name and --nikon-wtu-guid.

Profile Sampler Contact Sheet

sampler renders one thumbnail per XMP file from emulations/ and builds a structured contact sheet grouped by shared profile-name prefixes. For example, Kodak profiles are shown under progressively deeper headings like Kodak, Kodak Portra, Kodak Portra 400, and Kodak Portra 400 Grainy; indentation makes the level visible. Each thumbnail is developed with its profile-specific generated RawTherapee .pp3 files, including Film Simulation for the Hald, which applies the LUT during RAW development, before the grain stage. Like batch, sampler renders half of the detected CPU threads in parallel by default; override with --jobs N. Thumbnail longest edge defaults to 512 px:

--jobs 8
--thumbnail-long-edge 768
--jpg-quality 92
--no-grain

Use a non-default convert binary or write a progressive sampler JPEG with:

--convert /path/to/convert
--progressive

JPEG Export Options

apply, batch, and daemon support the same final JPG controls. batch and daemon also accept --output-format jpg|tiff; TIFF batch output is written as 16-bit Zip-compressed .tif. sampler supports --jpg-quality, --jpeg-subsampling, --strip-metadata, and --progressive for generated sampler JPEGs, and accepts .jpg/.jpeg or .html outputs (HTML mode produces a clickable gallery with lazy thumbnails).

--jpg-quality 90
--long-edge 3000
--jpeg-subsampling s444
--progressive-jpeg
--strip-metadata

Resize options:

  • --resize 3000x3000> passes explicit GraphicsMagick resize geometry.
  • --long-edge 3000 constrains the longest edge to 3000 px.
  • --max-width 3000 constrains width only.
  • --max-height 2000 constrains height only.
  • --max-width 3000 --max-height 2000 constrains both dimensions.

Use one resize mode at a time: --resize, --long-edge, or --max-width/--max-height.

JPEG subsampling values:

  • s444: best quality, no chroma subsampling
  • s422: balanced horizontal chroma subsampling
  • s420: smaller files with horizontal and vertical chroma subsampling

Profile Selection

--profile is optional for apply, batch, daemon, and the desktop app. If it is omitted entirely, mini-film asks RawTherapee to develop the RAW with its default settings and does not apply Hald, PP3, profile adjustments, or profile-derived grain. When provided, --profile accepts:

  • a Hald PNG path
  • a RawTherapee .pp3 path
  • an emulation XMP path containing crs:Look plus optional grain settings
  • an emulation name, searched under emulations/ using case-insensitive fuzzy matching
  • a generated Hald name, searched under --hald-dir, which defaults to $HOME/.cache/mini-film/hald

RGBTable XMPs under profiles/ are internal lookup tables. apply, batch, and sampler do not use them as user-facing emulations; they are only used to resolve linked crs:Look UUID/name references from emulation XMPs. mini-film generates or reuses a cached Hald from the linked profile under $HOME/.cache/mini-film/hald, generates temporary RawTherapee .pp3 files for supported XMP adjustments and Film Simulation, lets RawTherapee apply the Hald, then applies the emulation grain settings.

Profile Info

Print parsed details for a user-facing emulation or an internal RGBTable profile:

cargo run --release -- info \
  'Polaroid 600 v3 grainy' \
  --profiles-root /path/to/profile-library

info resolves emulation names under emulations/, direct emulation XMP paths, direct internal profile XMP paths, internal profile names under profiles/, and cached Hald PNGs under --hald-dir. For emulations, it prints the preset identity, linked Look, linked internal RGBTable profile, cached Hald path, profile-side tone/color/sharpening adjustments, and emulation-side grain/adjustments.

RawTherapee PP3 Output

Print the generated RawTherapee PP3 for a profile:

cargo run --release -- pp3 \
  'Polaroid 600 v3 grainy' \
  --profiles-root /path/to/profile-library \
  --output polaroid-600-v3.pp3

pp3 uses the same profile/emulation resolver as info. It writes to /dev/stdout by default, or to --output. The output contains the RawTherapee adjustment profile sections that mini-film would pass to rawtherapee-cli, followed by the Film Simulation section pointing at the cached Hald PNG.

Nikon Picture Control Output

Fit an emulation XMP, internal RGBTable XMP, or Hald PNG into a Nikon classic .NCP Picture Control:

cargo run --release -- nikon \
  'Polaroid 600 v3 grainy' \
  --profiles-root /path/to/profile-library \
  --output polaroid-600-v3.ncp \
  --report polaroid-600-v3.ncp.txt

The nikon command writes a real classic NCP file using a neutral base Picture Control plus a fitted 257-point user-defined luminosity curve. It also estimates coarse saturation, hue, and sharpening fields from the profile. Use --name 'Short Name' to set the in-camera Picture Control name; NCP names are ASCII and short, so mini-film sanitizes and truncates them.

This is necessarily lossy. Nikon classic NCP does not store a full 3D LUT, RGBTable, Hald CLUT, or grain model. Color-specific film behavior is compressed into a 1D luma curve plus coarse sliders. Use the optional report to inspect mean/max luma and color error before trusting the result.

Processing Split

RawTherapee handles:

  • RAW development and Hald CLUT application through Film Simulation
  • Exposure2012, Contrast2012, Highlights2012, Shadows2012, Whites2012, Blacks2012
  • Saturation, Vibrance
  • ToneCurvePV2012 and per-channel ToneCurvePV2012Red/Green/Blue
  • ParametricShadows/Darks/Lights/Highlights and split points
  • HSL HueAdjustment*, SaturationAdjustment*, LuminanceAdjustment*
  • calibration-style RedHue/RedSaturation, GreenHue/GreenSaturation, BlueHue/BlueSaturation
  • Clarity2012 as a RawTherapee luminance-contrast approximation
  • profile sharpening fields in generated .pp3 files: Sharpness, SharpenRadius, SharpenDetail, SharpenEdgeMasking

mini-film internally handles:

  • resolving emulation XMPs to internal RGBTable XMPs under profiles/
  • decoding RGBTable payloads and generating RGBTable-only Hald PNGs
  • procedural grain from Lightroom grain fields

ImageMagick/GraphicsMagick convert handles:

  • final resize, bit depth, metadata stripping, JPEG quality/subsampling, progressive JPEG, TIFF Zip compression, and TIFF/JPEG encoding
  • structured sampler contact sheet rendering from mini-film's generated SVG layout

RAW Development

mini-film uses RawTherapee as its only RAW engine. TIFF outputs and explicit --keep-intermediate runs render a 16-bit TIFF intermediate with:

rawtherapee-cli -q -Y [-p generated.pp3 ...] -o intermediate.tif -t -b16 -c input.RAW

JPEG-bound apply, batch, and sampler runs ask RawTherapee for an 8-bit JPEG intermediate instead:

rawtherapee-cli -q -Y [-p generated.pp3 ...] -o intermediate.jpg -j95 -js3 -c input.RAW

Sampler also adds a temporary RawTherapee resize profile so each RAW development produces a thumbnail-sized JPEG instead of a full-size TIFF.

Use a non-default RawTherapee binary path with:

--rawtherapee /path/to/rawtherapee-cli

Grain

Lightroom grain fields are read from preset XMPs:

  • crs:GrainAmount
  • crs:GrainSize
  • crs:GrainFrequency

Grain is rendered internally after RawTherapee. TIFF outputs use the 16-bit grain path; JPEG outputs use the optimized 8-bit grain path. Disable it with:

Set deterministic variation with:

When using a Hald PNG directly, pass grain manually:

or use a preset:

--grain-preset light
--grain-preset medium
--grain-preset heavy

Color Noise Reduction

Since v3.1, mini-film can generate a short temporary RawTherapee pp3 block for directional pyramid color denoising when source EXIF ISO is above a threshold.

  • Controlled by --color-noise-iso-threshold on apply, batch, daemon, and sampler.
  • Default threshold is 1600.
  • Set to 0 to disable color-noise processing.
  • The ISO is read from raw EXIF; when no ISO is available, the step is skipped.

The thresholds use stepped levels:

  • ISO >= 25_600: very strong color-denoise
  • ISO >= 6_400: strong
  • ISO >= 1_600: moderate (default threshold)
  • below threshold: skipped

The denoise block is appended as an extra generated [Directional Pyramid Denoising] section in the RawTherapee profile chain, after emulation/RAW adjustments and film simulation and before mini-film procedural grain.

Example:

--color-noise-iso-threshold 1600   # default
--color-noise-iso-threshold 0      # disable

RawTherapee Lens Corrections

Mini-film can optionally enable RawTherapee lens-correction controls. This is off by default and available on apply, batch, sampler, and daemon via:

--lens-corrections
--lens-corrections all
--lens-corrections distortion,ca,vignetting

When no value is provided, --lens-corrections enables all supported items. You can also pass any subset of:

  • distortion
  • ca or chromatic-aberration
  • vignetting / vignette
  • all

The generated section is inserted into the temporary pp3 stack as:

[LensProfile]
LcMode=lfauto
UseDistortion=<true|false>
UseVignette=<true|false>
UseCA=<true|false>

Caveat

This does not fully clone Adobe Camera Raw. It decodes and applies the profile RGB table, maps supported profile tone/color/sharpening fields into generated RawTherapee .pp3 files, uses RawTherapee for RAW development, and emulates Lightroom grain. Adobe-specific tone mapping, local contrast, sharpening, and camera matching may still differ.