colors from wallpapers

This commit is contained in:
Lennart J. Kurzweg (Nx2)
2024-09-04 16:59:05 +02:00
parent ce84d681e0
commit d7cc5f77d7
5 changed files with 190 additions and 20 deletions

13
flake-modules/colors.json Normal file
View File

@@ -0,0 +1,13 @@
{
"base": {
"foreground": "#eedce2",
"background": "#221016"
},
"to_alter": {
"accent": "#ac5271",
"secondary": "#f20c5b",
"tertiary": "#d5a287",
"special": "#51ac8d",
"weird": "#0cf2a3"
}
}

View File

@@ -12,30 +12,34 @@ pkgs: rec {
bright = (0.5); bright = (0.5);
alter-set = let f = lib.alter-luminace-hex; in color-name: color-value: { base = color-value; dark = f color-value dark; bright = f color-value bright; }; alter-set = let f = lib.alter-luminace-hex; in color-name: color-value: { base = color-value; dark = f color-value dark; bright = f color-value bright; };
alter = let f = lib.alter-luminace-hex; in color-value: { base = color-value; dark = f color-value dark; bright = f color-value bright; }; alter = let f = lib.alter-luminace-hex; in color-value: { base = color-value; dark = f color-value dark; bright = f color-value bright; };
# ccolor = builtins.mapAttrs alter-set (builtins.fromJSON (builtins.readFile ./colors.json));
ccolor = builtins.mapAttrs alter-set { ccolor = builtins.mapAttrs alter-set {
black = "#000022"; # "#111111" "#001100"; black = "#111111"; # "#111111" "#001100";
white = "#ddddff"; # "#dddddd" "#66dd66"; white = "#dddddd"; # "#dddddd" "#66dd66";
blue = "#4422ff"; # "#3333dd" "#003300"; blue = "#4444dd"; # "#3333dd" "#003300";
cyan = "#11dddd"; # "#11dddd" "#00dd55"; cyan = "#44dddd"; # "#11dddd" "#00dd55";
green = "#11dd44"; # "#11dd11" "#11dd11"; green = "#44dd44"; # "#11dd11" "#11dd11";
magenta = "#6622dd"; # "#dd11dd" "#005500"; magenta = "#dd44dd"; # "#dd11dd" "#005500";
red = "#dd1166"; # "#dd1111" "#00aa00"; red = "#dd4444"; # "#dd1111" "#00aa00";
yellow = "#dd6611"; # "#dddd11" "#ffff00"; yellow = "#dd4444"; # "#dddd11" "#ffff00";
}; };
xcolor = with ccolor; rec { facolor = builtins.mapAttrs alter-set (builtins.fromJSON (builtins.readFile ./colors.json)).to_alter;
background = black.dark; fbcolor = (builtins.fromJSON (builtins.readFile ./colors.json)).base;
foreground = white.base; fcolor = facolor // fbcolor;
border = red.base; xcolor = with ccolor; with fcolor; rec {
border2 = blue.base; background = "#000000";
accent = blue; # foreground = "#dddddd";
secondary = cyan; # accent = blue;
tertiary = magenta; # secondary = cyan;
special = yellow; # tertiary = magenta;
weird = green; # special = yellow;
# weird = green;
positive = alter "#00dd00"; positive = alter "#00dd00";
negative = alter "#dd0000"; negative = alter "#dd0000";
border = accent.base;
border2 = secondary.base;
}; };
in ccolor // xcolor; in ccolor // fcolor // xcolor;
font = { font = {
code = { code = {
name = "JetBrainsMono-NF"; name = "JetBrainsMono-NF";

View File

@@ -334,7 +334,7 @@ lib.mkIf (user != "tv")
"SUPER SHIFT, F5, exec, nx_gcal_event reauthenticate" "SUPER SHIFT, F5, exec, nx_gcal_event reauthenticate"
# "SUPER, F6," # "SUPER, F6,"
''SUPER, F8, exec, find ~/Pictures/wallpapers/* -type f -not -path "~/Pictures/wallpapers/.git/*" | sort -R | head -n 1 | xargs swww img --transition-type wipe --transition-angle 60 --transition-step 120 --transition-fps 120'' ''SUPER, F8, exec, find ~/Pictures/wallpapers/* -type f -not -path "~/Pictures/wallpapers/.git/*" | sort -R | head -n 1 | xargs swww img --transition-type wipe --transition-angle 60 --transition-step 120 --transition-fps 120''
# "SUPER, F9, hyprload,reload" "SUPER, F9, exec, change_colors_json $(swww query | sed -n 2p | sed -e 's-.*image: --g') && kitty -e sh -c 'nh home switch'"
# "SUPER, F10, hyprload,update" # "SUPER, F10, hyprload,update"
"SUPER, F11, exec, waybar" "SUPER, F11, exec, waybar"
"SUPER SHIFT, F11, exec, pkill waybar " "SUPER SHIFT, F11, exec, pkill waybar "

View File

@@ -0,0 +1,152 @@
{ pkgs-unstable, ... }:
{
home.packages = with pkgs-unstable; [
(writers.writePython3Bin "change_colors_json" {
libraries = with python3Packages; [ numpy pillow scikit-learn ];
flakeIgnore = [ "E302" "E305" "E226" "E501" ];
} /*python */ ''
from colorsys import hls_to_rgb, rgb_to_hls
import json
import sys
from typing import Literal, cast
from numpy.typing import NDArray
from sklearn.cluster import KMeans
import numpy as np
from PIL import Image
def fc(c: int) -> str:
assert c < 256
s = str(hex(c))[2:]
if c < 16:
return "0" + s
elif len(s) == 1:
return s + s
else:
return s
class Color(object):
def __init__(self, rgb: tuple[int, ...], frequency: float):
assert len(rgb) == 3, "RGB values must be a tuple of length 3"
self.rgb = cast(tuple[int, int, int], rgb)
self.freq: float = frequency
def __lt__(self, other: "Color") -> bool:
return self.freq < other.freq
@property
def hls(self) -> tuple[float, float, float]:
return rgb_to_hls(r=self.rgb[0] / 255, g=self.rgb[1] / 255, b=self.rgb[2] / 255)
@property
def luminance(self) -> float:
return np.dot(np.array([0.2126, 0.7152, 0.0722]), self.rgb)
def k_means_extraction(arr: NDArray[float], height: int, width: int, palette_size: int) -> list[Color]:
arr = np.reshape(arr, (width * height, -1))
model = KMeans(n_clusters=palette_size, n_init="auto", init="k-means++", random_state=2024)
labels = model.fit_predict(arr)
palette = np.array(model.cluster_centers_, dtype=int)
color_count = np.bincount(labels)
color_frequency = color_count / float(np.sum(color_count))
colors = []
for color, freq in zip(palette, color_frequency):
colors.append(Color(color, freq))
return colors
class Palette:
def __init__(self, colors: list[Color]):
self.colors = colors
self.frequencies = [c.freq for c in colors]
def __getitem__(self, item: int) -> Color:
return self.colors[item]
def __len__(self) -> int:
return self.number_of_colors
def ensure_color(c: Color, alter_sat: bool) -> list[int]:
hue, lum, sat = c.hls
if alter_sat:
new_sat = min(max(sat, 0.6) + 0.3, 1)
else:
new_sat = sat
new_lum = max(lum, 0.5)
r, g, b = hls_to_rgb(h=hue, l=new_lum, s=new_sat)
return [int(r*255), int(g*255), int(b*255)]
def list_to_hex(ilist: list[int]) -> str:
return f"#{fc(ilist[0])}{fc(ilist[1])}{fc(ilist[2])}"
def alter_hue(ilist: list[int], hue: int) -> list[int]:
assert hue >= 0 and hue <= 360
r, g, b = ilist
h, l, s = rgb_to_hls((r/255), (g/255), (b/255))
new_hue = (((h*360) + hue) % 360) / 360
r, g, b = hls_to_rgb(h=new_hue, l=l, s=s)
return [int(r*255), int(g*255), int(b*255)]
def alter_l(ilist: list[int], l_in_1_0: float) -> list[int]:
assert l_in_1_0 >= 0 and l_in_1_0 <= 1
r, g, b = ilist
h, _, s = rgb_to_hls((r/255), (g/255), (b/255))
r, g, b = hls_to_rgb(h=h, l=l_in_1_0, s=s)
return [int(r*255), int(g*255), int(b*255)]
def extract_colors(
image: str,
palette_size: int = 5,
resize: bool = True,
sort_mode: Literal["luminance", "frequency"] | None = None,
) -> Palette:
img = Image.open(image).convert("RGB")
# open the image
img = img.resize((256, 256))
width, height = img.size
arr = np.asarray(img)
colors = k_means_extraction(arr, height, width, palette_size)
if sort_mode == "luminance":
colors.sort(key=lambda c: c.luminance, reverse=False)
else:
colors.sort(reverse=True)
return Palette(colors)
if __name__ == "__main__":
try:
img = sys.argv[1]
except IndexError:
img = "/home/nx2/Pictures/wallpapers/absolute-cinema-acid.png"
palette = extract_colors(image=img, palette_size=3)
accent = ensure_color(c=palette[0], alter_sat=False)
secondary = ensure_color(c=palette[1], alter_sat=True)
tertiary = ensure_color(c=palette[2], alter_sat=False)
weird = alter_hue(ilist=secondary, hue=180)
special = alter_hue(ilist=accent, hue=180)
foreground = alter_l(accent, 0.9)
background = alter_l(accent, 0.1)
d = {
"base": {
"foreground": list_to_hex(foreground),
"background": list_to_hex(background)
},
"to_alter": {
"accent": list_to_hex(accent),
"secondary": list_to_hex(secondary),
"tertiary": list_to_hex(tertiary),
"special": list_to_hex(special),
"weird": list_to_hex(weird)
}
}
with open("/home/nx2/nix-dots/flake-modules/colors.json", "w") as f:
f.write(json.dumps(d, indent=4))
'')
];
}

View File

@@ -44,6 +44,7 @@
./home-modules/vale.nix ./home-modules/vale.nix
./home-modules/virt-manager.nix ./home-modules/virt-manager.nix
./home-modules/vscode.nix ./home-modules/vscode.nix
./home-modules/wallpaper-to-colors.nix
./home-modules/waybar.nix ./home-modules/waybar.nix
./home-modules/wlogout.nix ./home-modules/wlogout.nix
./home-modules/yazi.nix ./home-modules/yazi.nix