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 and 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 }, };
// Setup the palette to interpolate from let palette = vec![ [255, 0, 0], [0, 255, 0], [0, 0, 255], ];
// Setup the fast Gaussian RBF algorithm let (euclide, nearest) = (16.0, 0); let remapper = GaussianRemapper::new(&palette, euclide, nearest, SimpleColorSpace::default());
// Generate and remap a HALD:8 for the provided palette let haldclut = remapper.generatelut(8); // hald_clut.save("output.png").unwrap();
// 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:8 for the provided palette let haldclut = remapper.generatelut(4); // hald_clut.save("output.png").unwrap(); ```
Applying a LUT:
```rust,ignore use lutgen::identity::{generate, correct_image};
let identity = lutgen::identity::generate(8); let mut image = image::open("example-image.png").unwrap().to_rgb8();
correct_image(&mut image, &identity);
// image.save("output.png").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 exoquant::SimpleColorSpace; 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 (euclide, nearest) = (16.0, 0); let remapper = GaussianRemapper::new(&palette, euclide, nearest, SimpleColorSpace::default());
// Generate an image (generally an identity lut to use on other images) let mut identity = lutgen::identity::generate(8);
// Remap the image remapper.remapimage(&mut identity); // identity.save("v1hald_8.png").unwrap(); ```