A blazingly fast interpolated LUT generator and applicator for arbitrary and popular color palettes. Theme any image to your dekstop colorscheme!
Catppuccin Mocha Hald Clut
Example Image (Original)
Example Image (Corrected)
Install
bash
cargo install 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
-p, --palette lutgen -p
to view all options. Compatible with custom colors
-l, --level
[default: 8]
-a, --algorithm
[default: gaussian-rbf]
Possible values:
- shepards-method:
Shepard's method (RBF interpolation using the inverse distance function).
Params: --power, --nearest
- gaussian-rbf:
Radial Basis Function interpolation using the Gaussian function.
Params: --euclide, --nearest
- linear-rbf:
Radial Basis Function interpolation using a linear function. Params: --nearest
- gaussian-sampling:
Optimized version of the original ImageMagick approach which applies gaussian noise to each color and averages nearest neighbors together.
Params: --mean, --std_dev, --iterations
- nearest-neighbor:
Simple, non-interpolated, nearest neighbor alorithm
-m, --mean
[default: 0]
-s, --std-dev
[default: 20]
-i, --iterations
[default: 512]
--power <POWER>
Shepard algorithm's power parameter
[default: 4]
--euclide <EUCLIDE>
Gaussian RBF's euclide parameter
[default: 32]
--nearest <NUM_NEAREST>
Number of nearest palette colors to consider for RBF based algorithms. 0 uses unlimited (all) colors
[default: 16]
-h, --help Print help (see a summary with '-h')
-V, --version Print version ```
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
By default, the
bin
feature and dependencies are enabled. When used as a library, it's recommended to usedefault-features = false
to minimalize the dependency tree and build time.
Generating a LUT (simple):
```rust use exoquant::SimpleColorSpace; 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) = (96.0, 0); let remapper = GaussianRemapper::new(&palette, shape, nearest);
// 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, seed) = (0.0, 20.0, 512, 420); let remapper = GaussianSamplingRemapper::new( &palette, mean, stddev, iters, seed, SimpleColorSpace::default() );
// 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); 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) = (96.0, 0); let remapper = GaussianRemapper::new(&palette, shape, nearest);
// 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(); ```