-
Notifications
You must be signed in to change notification settings - Fork 12
/
generate.mjs
80 lines (66 loc) · 2 KB
/
generate.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// [email protected] or higher needed
import { ColorType, colorTypeToChannels, encode } from "png-tools";
import fs from "fs/promises";
import { deflate } from "pako";
import {
lab_to_lch,
lch_to_lab,
rgb_to_oklab,
angle_delta,
oklab_to_rgb,
} from "./util/color.mjs";
import * as path from "path";
import { fileURLToPath } from "url";
const colorType = ColorType.RGB;
const channels = colorTypeToChannels(colorType);
const size = 512;
const data = new Uint8ClampedArray(size * size * channels);
const SelectiveColor = (hueTarget, hueRange) => {
return (rgb) => {
let [R, G, B] = rgb;
let [L, C, H] = lab_to_lch(rgb_to_oklab([R, G, B]));
const hueDelta = Math.abs(angle_delta(H, hueTarget));
const hueFact = 1 - Math.max(0, Math.min(1, hueDelta / hueRange));
// desaturate
C *= hueFact;
return oklab_to_rgb(lch_to_lab([L, C, H]));
};
};
// Set this to null if you don't want to filter the LUT
// and would like to just generate the base PNG
// const filter = null;
// Here we target a specific hue (34º) and smoothly desaturate as we
// move away from that by 25º in either dir
const filter = SelectiveColor(34, 25);
for (let by = 0; by < 8; by++) {
for (let bx = 0; bx < 8; bx++) {
for (let g = 0; g < 64; g++) {
for (let r = 0; r < 64; r++) {
const x = r + bx * 64;
const y = g + by * 64;
const idx = x + y * size;
let R = Math.floor((r * 255.0) / 63.0 + 0.5);
let G = Math.floor((g * 255.0) / 63.0 + 0.5);
let B = Math.floor(((bx + by * 8.0) * 255.0) / 63.0 + 0.5);
if (filter) {
[R, G, B] = filter([R, G, B]);
}
data[idx * channels + 0] = R;
data[idx * channels + 1] = G;
data[idx * channels + 2] = B;
}
}
}
}
const png = encode(
{
colorType,
width: size,
height: size,
data,
},
deflate
);
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const file = path.resolve(__dirname, "lookup_selective_color.png");
await fs.writeFile(file, png);