Convert.PerceptualPerceptual color converter using LAB color space for nearest-neighbor matching.
This converter uses the CIE LAB color space to find the nearest terminal color, which provides better perceptual accuracy than Euclidean RGB distance. Colors that appear similar to humans will be numerically close in LAB space.
The implementation delegates nearest-color search to the palette modules (Spectrum_palettes.Terminal.Basic and Spectrum_palettes.Terminal.Xterm256), which use octree-based spatial indexing in LAB space for efficient lookup.
For ANSI-16 quantization, searches the full 16-color palette. For ANSI-256 quantization, searches only xterm codes 16-255 (color cube + greys), excluding basic codes 0-15.
Convert RGB color to ANSI-256 color code (0-255).
Uses perceptual color matching in LAB space to find the nearest xterm-256 palette color (codes 16-255, excluding basic 16 colors).
(* Convert orange to nearest xterm-256 color *)
let orange = Gg.Color.v_srgb 1.0 0.5 0.0 in
let code = Perceptual.rgb_to_ansi256 orange in
Printf.printf "\027[38;5;%dm■\027[0m Orange is code %d\n" code code (* Find nearest color for a purple shade *)
let purple = Gg.Color.v_srgb 0.6 0.2 0.8 in
let code = Perceptual.rgb_to_ansi256 purple in
Printf.printf "Purple maps to xterm-256 code: %d\n" code (* Convert multiple colors *)
let colors = [
("red", Gg.Color.v_srgb 0.9 0.1 0.1);
("green", Gg.Color.v_srgb 0.1 0.9 0.1);
("blue", Gg.Color.v_srgb 0.1 0.1 0.9);
] in
List.iter (fun (name, color) ->
let code = Perceptual.rgb_to_ansi256 color in
Printf.printf "%s -> %d\n" name code
) colorsConvert RGB color to ANSI-16 basic color code (30-37, 90-97).
Uses perceptual color matching in LAB space to find the nearest of the 16 basic ANSI colors.
(* Convert red to nearest basic color *)
let red = Gg.Color.v_srgb 0.9 0.1 0.1 in
let code = Perceptual.rgb_to_ansi16 red in
Printf.printf "\027[%dm■\027[0m Red is code %d\n" code code
(* Likely maps to bright red: code 91 *) (* Test basic vs bright color mapping *)
let dark_green = Gg.Color.v_srgb 0.0 0.5 0.0 in
let bright_green = Gg.Color.v_srgb 0.0 1.0 0.0 in
let dark_code = Perceptual.rgb_to_ansi16 dark_green in
let bright_code = Perceptual.rgb_to_ansi16 bright_green in
Printf.printf "Dark green: %d, Bright green: %d\n"
dark_code bright_code
(* Dark: 32, Bright: 92 *) (* Quantize a gradient to basic colors *)
for i = 0 to 10 do
let intensity = float_of_int i /. 10. in
let color = Gg.Color.v_srgb intensity 0.0 0.0 in
let code = Perceptual.rgb_to_ansi16 color in
Printf.printf "\027[%dm■\027[0m " code
done;
print_newline ()