summaryrefslogtreecommitdiff
path: root/scheme
diff options
context:
space:
mode:
Diffstat (limited to 'scheme')
-rwxr-xr-xscheme/autoadjust.py76
-rwxr-xr-xscheme/gen-scheme.fish37
-rwxr-xr-xscheme/score.py57
3 files changed, 103 insertions, 67 deletions
diff --git a/scheme/autoadjust.py b/scheme/autoadjust.py
index dd007ab..7ee28d7 100755
--- a/scheme/autoadjust.py
+++ b/scheme/autoadjust.py
@@ -2,6 +2,7 @@
import sys
from colorsys import hls_to_rgb, rgb_to_hls
+from pathlib import Path
from materialyoucolor.dynamiccolor.material_dynamic_colors import (
DynamicScheme,
@@ -17,7 +18,6 @@ from materialyoucolor.scheme.scheme_neutral import SchemeNeutral
from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow
from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot
from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant
-from materialyoucolor.utils.color_utils import argb_from_rgb
light_colours = [
"dc8a78",
@@ -101,7 +101,9 @@ def grayscale(hls: HLS, light: bool) -> HLS:
def mix(a: HLS, b: HLS, w: float) -> HLS:
r1, g1, b1 = hls_to_rgb(*a)
r2, g2, b2 = hls_to_rgb(*b)
- return rgb_to_hls(r1 * (1 - w) + r2 * w, g1 * (1 - w) + g2 * w, b1 * (1 - w) + b2 * w)
+ return rgb_to_hls(
+ r1 * (1 - w) + r2 * w, g1 * (1 - w) + g2 * w, b1 * (1 - w) + b2 * w
+ )
def darken(colour: HLS, amount: float) -> HLS:
@@ -161,16 +163,23 @@ def get_scheme(scheme: str) -> DynamicScheme:
return SchemeVibrant
+def get_alt(i: int) -> str:
+ names = ["default", "alt1", "alt2"]
+ return names[i]
+
+
if __name__ == "__main__":
light = sys.argv[1] == "light"
scheme = sys.argv[2]
- colours_in = sys.argv[3].split(" ")
+ primaries = sys.argv[3].split(" ")
+ colours_in = sys.argv[4].split(" ")
+ out_path = sys.argv[5]
base = light_colours if light else dark_colours
chroma_mult = 1.5 if light else 1.2
# Convert to HLS
- colours = [hex_to_hls(c) for c in colours_in[1:]]
+ colours = [hex_to_hls(c) for c in colours_in]
# Sort colours and turn into dict
colours = smart_sort(colours, base)
@@ -192,36 +201,45 @@ if __name__ == "__main__":
colour.chroma *= chroma_mult
- colours[name] = hex_to_hls("{:02X}{:02X}{:02X}".format(*colour.to_rgba()[:3]))
+ colours[name] = hex_to_hls(
+ "{:02X}{:02X}{:02X}".format(*colour.to_rgba()[:3])
+ )
# Success and error colours
colours["success"] = mix(colours["green"], hex_to_hls(base[8]), 0.8)
colours["error"] = mix(colours["red"], hex_to_hls(base[4]), 0.8)
# Layers and accents
- material = {}
- primary_scheme = MatScheme(Hct.from_int(int(f"0xFF{colours_in[0]}", 16)), not light, 0)
- for colour in vars(MaterialDynamicColors).keys():
- colour_name = getattr(MaterialDynamicColors, colour)
- if hasattr(colour_name, "get_hct"):
- rgb = colour_name.get_hct(primary_scheme).to_rgba()[:3]
- material[colour] = hex_to_hls("{:02X}{:02X}{:02X}".format(*rgb))
+ for i, primary in enumerate(primaries):
+ material = {}
+ primary_scheme = MatScheme(
+ Hct.from_int(int(f"0xFF{primary}", 16)), not light, 0
+ )
+ for colour in vars(MaterialDynamicColors).keys():
+ colour_name = getattr(MaterialDynamicColors, colour)
+ if hasattr(colour_name, "get_hct"):
+ rgb = colour_name.get_hct(primary_scheme).to_rgba()[:3]
+ material[colour] = hex_to_hls("{:02X}{:02X}{:02X}".format(*rgb))
- colours["primary"] = material["primary"]
- colours["secondary"] = material["secondary"]
- colours["tertiary"] = material["tertiary"]
- colours["text"] = material["onBackground"]
- colours["subtext1"] = material["onSurfaceVariant"]
- colours["subtext0"] = material["outline"]
- colours["overlay2"] = mix(material["surface"], material["outline"], 0.86)
- colours["overlay1"] = mix(material["surface"], material["outline"], 0.71)
- colours["overlay0"] = mix(material["surface"], material["outline"], 0.57)
- colours["surface2"] = mix(material["surface"], material["outline"], 0.43)
- colours["surface1"] = mix(material["surface"], material["outline"], 0.29)
- colours["surface0"] = mix(material["surface"], material["outline"], 0.14)
- colours["base"] = material["surface"]
- colours["mantle"] = darken(material["surface"], 0.03)
- colours["crust"] = darken(material["surface"], 0.05)
+ colours["primary"] = material["primary"]
+ colours["secondary"] = material["secondary"]
+ colours["tertiary"] = material["tertiary"]
+ colours["text"] = material["onBackground"]
+ colours["subtext1"] = material["onSurfaceVariant"]
+ colours["subtext0"] = material["outline"]
+ colours["overlay2"] = mix(material["surface"], material["outline"], 0.86)
+ colours["overlay1"] = mix(material["surface"], material["outline"], 0.71)
+ colours["overlay0"] = mix(material["surface"], material["outline"], 0.57)
+ colours["surface2"] = mix(material["surface"], material["outline"], 0.43)
+ colours["surface1"] = mix(material["surface"], material["outline"], 0.29)
+ colours["surface0"] = mix(material["surface"], material["outline"], 0.14)
+ colours["base"] = material["surface"]
+ colours["mantle"] = darken(material["surface"], 0.03)
+ colours["crust"] = darken(material["surface"], 0.05)
- for name, colour in colours.items():
- print(f"{name} {hls_to_hex(*colour)}")
+ out_file = Path(f"{out_path}/{scheme}/{get_alt(i)}/{sys.argv[1]}.txt")
+ out_file.parent.mkdir(parents=True, exist_ok=True)
+ colour_arr = [
+ f"{name} {hls_to_hex(*colour)}" for name, colour in colours.items()
+ ]
+ out_file.write_text("\n".join(colour_arr))
diff --git a/scheme/gen-scheme.fish b/scheme/gen-scheme.fish
index c034980..488ee27 100755
--- a/scheme/gen-scheme.fish
+++ b/scheme/gen-scheme.fish
@@ -5,30 +5,29 @@ set -l src (dirname (status filename))
. $src/../util.fish
test -f "$argv[1]" && set -l img (realpath "$argv[1]") || set -l img $C_STATE/wallpaper/thumbnail.jpg
-contains -- "$argv[2]" light dark && set -l theme $argv[2] || set -l theme dark
set -l variants vibrant tonalspot expressive fidelity fruitsalad rainbow neutral content monochrome
-set -l hash (sha1sum $img | cut -d ' ' -f 1)
+contains -- "$argv[2]" $variants && set -l variant $argv[2] || set -l variant (cat $C_STATE/scheme/current-variant.txt 2> /dev/null)
+contains -- "$variant" $variants || set -l variant tonalspot
-# Cache schemes
-mkdir -p $C_CACHE/schemes
-set -l dirty_variants
-if test -d $C_CACHE/schemes/$hash
- for variant in $variants
- test -f $C_CACHE/schemes/$hash/$variant/$theme.txt || set -a dirty_variants $variant
- end
-else
- set dirty_variants $variants
-end
+set -l hash (sha1sum $img | cut -d ' ' -f 1)
-if test -n "$dirty_variants"
- # Generate schemes for variants that need it
+# Cache scheme
+if ! test -d $C_CACHE/schemes/$hash/$variant
set -l colours ($src/score.py $img)
- parallel "mkdir -p $C_CACHE/schemes/$hash/{} && $src/autoadjust.py $theme {} '$colours' | head -c -1 > $C_CACHE/schemes/$hash/{}/$theme.txt" ::: $dirty_variants
+ $src/autoadjust.py dark $variant $colours $C_CACHE/schemes/$hash
+ $src/autoadjust.py light $variant $colours $C_CACHE/schemes/$hash
end
-# Copy schemes from cache
-for variant in $variants
- mkdir -p $src/../data/schemes/dynamic/$variant
- cp $C_CACHE/schemes/$hash/$variant/$theme.txt $src/../data/schemes/dynamic/$variant/$theme.txt
+# Copy scheme from cache
+rm -rf $src/../data/schemes/dynamic
+cp -r $C_CACHE/schemes/$hash/$variant $src/../data/schemes/dynamic
+
+# Update if current
+set -l variant (string match -gr 'dynamic-(.*)' (cat $C_STATE/scheme/current-name.txt 2> /dev/null))
+if test -n "$variant"
+ # If variant doesn't exist, use default
+ test -d $src/../data/schemes/dynamic/$variant || set -l variant default
+ # Apply scheme
+ $src/main.fish dynamic $variant $MODE > /dev/null
end
diff --git a/scheme/score.py b/scheme/score.py
index 531046f..92ebbb7 100755
--- a/scheme/score.py
+++ b/scheme/score.py
@@ -2,10 +2,10 @@
import sys
-from materialyoucolor.quantize import ImageQuantizeCelebi
-from materialyoucolor.hct import Hct
-from materialyoucolor.utils.math_utils import sanitize_degrees_int, difference_degrees
from materialyoucolor.dislike.dislike_analyzer import DislikeAnalyzer
+from materialyoucolor.hct import Hct
+from materialyoucolor.quantize import ImageQuantizeCelebi
+from materialyoucolor.utils.math_utils import difference_degrees, sanitize_degrees_int
class Score:
@@ -20,7 +20,7 @@ class Score:
pass
@staticmethod
- def score(colors_to_population: dict) -> list[int]:
+ def score(colors_to_population: dict) -> tuple[list[Hct], list[Hct]]:
desired = 14
filter_enabled = False
dislike_filter = True
@@ -72,7 +72,8 @@ class Score:
chosen_colors = []
for difference_degrees_ in range(90, 0, -1):
chosen_colors.clear()
- for hct in [item["hct"] for item in scored_hct]:
+ for item in scored_hct:
+ hct = item["hct"]
duplicate_hue = any(
difference_degrees(hct.hue, chosen_hct.hue) < difference_degrees_
for chosen_hct in chosen_colors
@@ -85,31 +86,49 @@ class Score:
break
# Get primary colour
- got_primary = False
+ primary = None
for cutoff in range(20, 0, -1):
for item in scored_hct:
if item["hct"].chroma > cutoff and item["hct"].tone > cutoff * 3:
- chosen_colors.insert(0, item["hct"])
- got_primary = True
+ primary = item["hct"]
break
- if got_primary:
+ if primary:
+ break
+
+ # Choose distinct primaries
+ chosen_primaries = [primary]
+ for difference_degrees_ in range(90, 14, -1):
+ chosen_primaries = [primary]
+ for item in scored_hct:
+ hct = item["hct"]
+ duplicate_hue = any(
+ difference_degrees(hct.hue, chosen_hct.hue) < difference_degrees_
+ for chosen_hct in chosen_primaries
+ )
+ if not duplicate_hue:
+ chosen_primaries.append(hct)
+ if len(chosen_primaries) >= 3:
+ break
+ if len(chosen_primaries) >= 3:
break
# Fix disliked colours
if dislike_filter:
- for chosen_hct in chosen_colors:
- chosen_colors[chosen_colors.index(chosen_hct)] = (
- DislikeAnalyzer.fix_if_disliked(chosen_hct)
- )
+ for i, chosen_hct in enumerate(chosen_primaries):
+ chosen_primaries[i] = DislikeAnalyzer.fix_if_disliked(chosen_hct)
+ for i, chosen_hct in enumerate(chosen_colors):
+ chosen_colors[i] = DislikeAnalyzer.fix_if_disliked(chosen_hct)
- return chosen_colors
+ return chosen_primaries, chosen_colors
if __name__ == "__main__":
img = sys.argv[1]
+ mode = sys.argv[2] if len(sys.argv) > 2 else "hex"
- colours = ImageQuantizeCelebi(img, 1, 128)
- colours = [c.to_rgba()[:3] for c in Score.score(colours)]
-
- # print("".join(["\x1b[48;2;{};{};{}m \x1b[0m".format(*colour) for colour in colours]))
- print(" ".join(["{:02X}{:02X}{:02X}".format(*colour) for colour in colours]))
+ colours = Score.score(ImageQuantizeCelebi(img, 1, 128))
+ for l in colours:
+ if mode != "hex":
+ print("".join(["\x1b[48;2;{};{};{}m \x1b[0m".format(*c.to_rgba()[:3]) for c in l]))
+ if mode != "swatch":
+ print(" ".join(["{:02X}{:02X}{:02X}".format(*c.to_rgba()[:3]) for c in l]))