feat: add lut node script, renders, and examples
55
lut/apply.sh
Executable file
|
@ -0,0 +1,55 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
# ensure src is where the script is located, even if symlinked
|
||||||
|
src="$( cd -- "$( dirname -- "$(readlink -f "${BASH_SOURCE[0]}" || ${BASH_SOURCE[0]})" )" &> /dev/null && pwd )/src"
|
||||||
|
|
||||||
|
print_usage() {
|
||||||
|
name=`basename $0`
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $name -i <image1> ... [args]
|
||||||
|
-i image : Image to apply LUT to, can be repeated
|
||||||
|
-f flavor : Flavor to apply, can be repeated. Defaults to all
|
||||||
|
-n noise : LUT Noise level (0-4). Defaults to 2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
noise="2"
|
||||||
|
images=""
|
||||||
|
flavors=""
|
||||||
|
|
||||||
|
while getopts ':f:i:n:' flag; do
|
||||||
|
case "$flag" in
|
||||||
|
n)
|
||||||
|
if [[ $OPTARG -gt 4 ]]; then
|
||||||
|
echo "Invalid noise level (0-4)"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
noise=$OPTARG
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
f) flavors="$flavors $OPTARG" ;;
|
||||||
|
i) images="$images `realpath $OPTARG`" ;;
|
||||||
|
*) print_usage
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$images" == "" ]]; then
|
||||||
|
print_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$flavors" == "" ]]; then
|
||||||
|
flavors="Oled Mocha Macchiato Frappe Latte"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for file in $images; do
|
||||||
|
echo "Performing magick on `basename $file` (noise: $noise)"
|
||||||
|
for flavor in $flavors; do
|
||||||
|
printf "$flavor ..."
|
||||||
|
out="${file%%.*}-${flavor}.png"
|
||||||
|
magick $file "$src/noise_$noise/Catppuccin ${flavor}.png" -hald-clut "$out"
|
||||||
|
printf "\r$flavor ✓ ($out)\n"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
BIN
lut/example/preview.png
Normal file
After Width: | Height: | Size: 3.6 MiB |
BIN
lut/example/simon-berger-unsplash-Frappe.png
Normal file
After Width: | Height: | Size: 18 MiB |
BIN
lut/example/simon-berger-unsplash-Latte.png
Normal file
After Width: | Height: | Size: 19 MiB |
BIN
lut/example/simon-berger-unsplash-Macchiato.png
Normal file
After Width: | Height: | Size: 18 MiB |
BIN
lut/example/simon-berger-unsplash-Mocha.png
Normal file
After Width: | Height: | Size: 19 MiB |
BIN
lut/example/simon-berger-unsplash-Oled.png
Normal file
After Width: | Height: | Size: 19 MiB |
BIN
lut/example/simon-berger-unsplash.jpg
Normal file
After Width: | Height: | Size: 2.5 MiB |
BIN
lut/src/noise_0/Catppuccin Frappe.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
lut/src/noise_0/Catppuccin Latte.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
lut/src/noise_0/Catppuccin Macchiato.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
lut/src/noise_0/Catppuccin Mocha.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
lut/src/noise_0/Catppuccin Oled.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
lut/src/noise_1/Catppuccin Frappe.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_1/Catppuccin Latte.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_1/Catppuccin Macchiato.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_1/Catppuccin Mocha.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_1/Catppuccin Oled.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_2/Catppuccin Frappe.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_2/Catppuccin Latte.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_2/Catppuccin Macchiato.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_2/Catppuccin Mocha.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_2/Catppuccin Oled.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_3/Catppuccin Frappe.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
lut/src/noise_3/Catppuccin Latte.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_3/Catppuccin Macchiato.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_3/Catppuccin Mocha.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_3/Catppuccin Oled.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_4/Catppuccin Frappe.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_4/Catppuccin Latte.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_4/Catppuccin Macchiato.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_4/Catppuccin Mocha.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
lut/src/noise_4/Catppuccin Oled.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
42
src/scripts/build_luts.mjs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import { exec } from "child_process";
|
||||||
|
import url from "url";
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
import util from "util";
|
||||||
|
import { variants } from "@catppuccin/palette";
|
||||||
|
|
||||||
|
const root = path.resolve(
|
||||||
|
url.fileURLToPath(new URL(".", import.meta.url)),
|
||||||
|
"..",
|
||||||
|
"..",
|
||||||
|
"dist"
|
||||||
|
);
|
||||||
|
|
||||||
|
const generateLut = async (name, out) => {
|
||||||
|
for (let i = 0; i <= 4; i++) {
|
||||||
|
fs.mkdirSync(path.join(root, `lut/noise_${i}`), { recursive: true });
|
||||||
|
process.stdout.clearLine(0);
|
||||||
|
process.stdout.cursorTo(0);
|
||||||
|
process.stdout.write(`${name}: [${i + 1}/5]`);
|
||||||
|
|
||||||
|
const cmd = `convert HALD:8 -duplicate 512 -attenuate ${i} +noise Gaussian -quantize LAB +dither -remap "${root}/png/${name}.png" -evaluate-sequence Mean "${root}/../lut/noise_${i}/${name}.png"`;
|
||||||
|
|
||||||
|
await util.promisify(exec)(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.stdout.clearLine(0);
|
||||||
|
process.stdout.cursorTo(0);
|
||||||
|
console.log(`${name}: done`);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
console.log("Generating Hald CLUTs...")
|
||||||
|
const flavors = Object.keys(variants);
|
||||||
|
for (let i = 0; i < flavors.length; i++) {
|
||||||
|
const name = flavors[i];
|
||||||
|
// formatted "pretty" name, Catppuccin <Flavor>
|
||||||
|
const pname = `Catppuccin ${name.charAt(0).toUpperCase() + name.slice(1)}`;
|
||||||
|
|
||||||
|
await generateLut(pname);
|
||||||
|
}
|
||||||
|
|