lutgen-rs

crate license ci publish

A blazingly fast interpolated LUT generator and applicator for arbitrary and popular color palettes. Theme any image to your dekstop colorscheme!


Example

Catppuccin Mocha Hald Clut
Example Image (Original)
Example Image (Corrected)

Usage

Note: The binary and library are still in a fairly experimental state, and breaking changes are made quite often. Any release that does make any changes as such, are bumped to 0.X.0

CLI

Source

bash git clone https://github.com/ozwaldorf/lutgen-rs cd lutgen-rs cargo install --path .

Releases

| Packaging Status | Installation Command | |------------------|----------------------| | Crates.io | cargo install lutgen | | AUR | yay -S lutgen-bin | | AUR | yay -S lutgen-git | | Alpine | apk add lutgen |

Helptext

```text A blazingly fast interpolated LUT generator and applicator for arbitrary and popular color palettes.

Usage: lutgen [OPTIONS] [CUSTOM_COLORS]... [COMMAND]

Commands: apply Correct an image using a hald clut, either generating it, or loading it externally help Print this message or the help of the given subcommand(s)

Arguments: [CUSTOM_COLORS]... Custom hexidecimal colors to add to the palette. If -p is not used to specify a base palette, at least 1 color is required

Options: -o, --output Path to write output to -p, --palette Predefined popular color palettes. Use lutgen -p to view all options. Compatible with custom colors -l, --level Hald level (ex: 8 = 512x512 image) [default: 8] -a, --algorithm Algorithm to remap the LUT with [default: gaussian-rbf] [possible values: shepards-method, gaussian-rbf, linear-rbf, gaussian-sampling, nearest-neighbor] -n, --nearest Number of nearest palette colors to consider at any given time for RBF based algorithms. 0 uses unlimited (all) colors [default: 16] -s, --shape Gaussian RBF's shape parameter. Higher means less gradient between colors, lower mean more [default: 96] --power Shepard algorithm's power parameter [default: 4] -m, --mean Gaussian sampling algorithm's mean parameter [default: 0] --std-dev Gaussian sampling algorithm's standard deviation parameter [default: 20] -i, --iterations Gaussian sampling algorithm's target number of samples to take for each color [default: 512] --completions [possible values: bash, elvish, fish, powershell, zsh] -h, --help Print help (see more with '--help') -V, --version Print version ```

Examples

Generating a LUT

bash lutgen -p catppuccin-mocha -o mocha_lut.png

Correcting an image with a LUT generated on the fly

bash lutgen -p catppuccin-mocha apply assets/simon-berger-unsplash.jpg -o mocha_version.png

Correcting an image with a pre-generated LUT

bash lutgen apply --hald-clut mocha_lut.png input.jpg

Correcting videos (using ffmpeg):

bash ffmpeg -i input.mkv -i hald_clut.png -filter_complex '[0][1] haldclut' output.mp4

Zsh Completions

bash lutgen --completions zsh > _lutgen sudo mv _lutgen /usr/local/share/zsh/site-functions/

Library

By default, the bin feature and dependencies are enabled. When used as a library, it's recommended to use default-features = false to minimalize the dependency tree and build time.

Generating a LUT (simple):

```rust use lutgen::{ GenerateLut, interpolation::{ GaussianRemapper, GaussianSamplingRemapper }, }; use lutgen_palettes::Palette;

// Get a premade palette let palette = Palette::CatppuccinMocha.get();

// Setup the fast Gaussian RBF algorithm let (shape, nearest, lumfactor) = (96.0, 0, 1.0); let remapper = GaussianRemapper::new(&palette, shape, nearest, lumfactor);

// Generate and remap a HALD:8 for the provided palette let haldclut = remapper.generatelut(8);

// hald_clut.save("output.png").unwrap();

// Setup another palette to interpolate from, with custom colors let palette = vec![ [255, 0, 0], [0, 255, 0], [0, 0, 255], ];

// Setup the slower Gaussian Sampling algorithm let (mean, stddev, iters, lumfactor, seed) = (0.0, 20.0, 512, 1.0, 420); let remapper = GaussianSamplingRemapper::new( &palette, mean, stddev, iters, lumfactor, seed );

// Generate and remap a HALD:4 for the provided palette let haldclut = remapper.generatelut(4);

// hald_clut.save("output.png").unwrap(); ```

Applying a LUT:

```rust use image::open;

use lutgen::{ identity::correctimage, interpolation::GaussianRemapper, GenerateLut, }; use lutgenpalettes::Palette;

// Generate a hald clut let palette = Palette::CatppuccinMocha.get(); let remapper = GaussianRemapper::new(&palette, 96.0, 0, 1.0); let haldclut = remapper.generatelut(8);

// Save the LUT for later hald_clut.save("docs/catppuccin-mocha-hald-clut.png").unwrap();

// Open an image to correct let mut externalimage = open("docs/example-image.jpg").unwrap().torgb8();

// Correct the image using the hald clut we generated correctimage(&mut externalimage, &hald_clut);

// Save the edited image external_image.save("docs/catppuccin-mocha.jpg").unwrap() ```

Remapping an image directly (advanced):

Note: While the remappers can be used directly on an image, it's much faster to remap a LUT and correct an image with that.

```rust use lutgen::{ GenerateLut, interpolation::{GaussianRemapper, InterpolatedRemapper}, };

// Setup the palette to interpolate from let palette = vec![ [255, 0, 0], [0, 255, 0], [0, 0, 255], ];

// Setup a remapper let (shape, nearest, lumfactor) = (96.0, 0, 1.0); let remapper = GaussianRemapper::new(&palette, shape, nearest, lumfactor);

// Generate an image (generally an identity lut to use on other images) let mut hald_clut = lutgen::identity::generate(8);

// Remap the image remapper.remapimage(&mut haldclut);

// hald_clut.save("output.png").unwrap(); ```

Tasks

Sources

Special Thanks