forked from Shinonome/caelestia-cli
scheme: optimise dynamic scheme gen
Make material schemes flavours of dynamic instead Remove dynamic-scheme subcommand Optimise scheme generation
This commit is contained in:
+18
-9
@@ -4,18 +4,27 @@ set -l src (dirname (status filename))
|
||||
|
||||
. $src/../util.fish
|
||||
|
||||
test -f "$argv[1]" && set -l img "$argv[1]" || set -l img $C_STATE/wallpaper/current
|
||||
set -l img (realpath $img)
|
||||
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
|
||||
test -n "$argv[3]" && set -l scheme $argv[3] || set -l scheme (cat $C_STATE/scheme/dynamic-scheme.txt 2> /dev/null || echo 'vibrant')
|
||||
|
||||
set -l variants vibrant tonalspot expressive fidelity fruitsalad rainbow neutral content
|
||||
|
||||
# Generate colours
|
||||
if test $scheme = 'monochrome'
|
||||
$src/autoadjust.py $theme $scheme (okolors $img -k 14)
|
||||
else
|
||||
test $theme = light && set -l lightness 50 || set -l lightness 70
|
||||
$src/autoadjust.py $theme $scheme (okolors $img -k 14 -w 0 -l $lightness)
|
||||
test $theme = light && set -l lightness 50 || set -l lightness 70
|
||||
set -l colours (okolors $img -k 14 -w 0 -l $lightness)
|
||||
for variant in $variants
|
||||
mkdir -p $src/../data/schemes/dynamic/$variant
|
||||
$src/autoadjust.py $theme $variant $colours > $src/../data/schemes/dynamic/$variant/$theme.txt
|
||||
end
|
||||
mkdir -p $src/../data/schemes/dynamic/monochrome
|
||||
$src/autoadjust.py $theme monochrome (okolors $img -k 14) > $src/../data/schemes/dynamic/monochrome/$theme.txt
|
||||
|
||||
set -la variants monochrome
|
||||
|
||||
# Generate layers and accents
|
||||
$src/genmaterial.py $img $theme $scheme | head -c -1 # Trim trailing newline
|
||||
set -l tmp (mktemp)
|
||||
$src/genmaterial.py $img $theme > $tmp
|
||||
for variant in $variants
|
||||
grep -FA 15 $variant $tmp | tail -15 | head -c -1 >> $src/../data/schemes/dynamic/$variant/$theme.txt
|
||||
end
|
||||
rm $tmp
|
||||
|
||||
+50
-74
@@ -6,9 +6,17 @@ from colorsys import hls_to_rgb, rgb_to_hls
|
||||
|
||||
from materialyoucolor.dynamiccolor.material_dynamic_colors import MaterialDynamicColors
|
||||
from materialyoucolor.hct import Hct
|
||||
from materialyoucolor.quantize import QuantizeCelebi
|
||||
from materialyoucolor.quantize import ImageQuantizeCelebi
|
||||
from materialyoucolor.scheme.scheme_content import SchemeContent
|
||||
from materialyoucolor.scheme.scheme_expressive import SchemeExpressive
|
||||
from materialyoucolor.scheme.scheme_fidelity import SchemeFidelity
|
||||
from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad
|
||||
from materialyoucolor.scheme.scheme_monochrome import SchemeMonochrome
|
||||
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.score.score import Score
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def darken(rgb: tuple[int, int, int], amount: float) -> tuple[int, int, int]:
|
||||
@@ -22,87 +30,55 @@ def mix(
|
||||
return tuple(round(rgb1[i] * (1 - amount) + rgb2[i] * amount) for i in range(3))
|
||||
|
||||
|
||||
def calculate_optimal_size(
|
||||
width: int, height: int, bitmap_size: int = 128
|
||||
) -> (int, int):
|
||||
image_area = width * height
|
||||
bitmap_area = bitmap_size**2
|
||||
scale = math.sqrt(bitmap_area / image_area) if image_area > bitmap_area else 1
|
||||
return max(1, round(width * scale)), max(1, round(height * scale))
|
||||
|
||||
|
||||
num_args = len(sys.argv)
|
||||
if num_args < 2:
|
||||
print('Usage: <path/to/image> [ "light" | "dark" ] [ <material_scheme> ]')
|
||||
print('Usage: <path/to/image> [ "light" | "dark" ]')
|
||||
sys.exit(1)
|
||||
|
||||
img = sys.argv[1]
|
||||
is_dark = num_args < 3 or sys.argv[2] != "light"
|
||||
scheme = "vibrant" if num_args < 4 else sys.argv[3]
|
||||
|
||||
with Image.open(sys.argv[1]) as image:
|
||||
if image.format == "GIF":
|
||||
image.seek(1)
|
||||
colours = ImageQuantizeCelebi(img, 1, 128)
|
||||
hct = Hct.from_int(Score.score(colours)[0])
|
||||
|
||||
if image.mode in ["L", "P"]:
|
||||
image = image.convert("RGB")
|
||||
for Scheme in (
|
||||
SchemeFruitSalad,
|
||||
SchemeExpressive,
|
||||
SchemeMonochrome,
|
||||
SchemeRainbow,
|
||||
SchemeTonalSpot,
|
||||
SchemeNeutral,
|
||||
SchemeFidelity,
|
||||
SchemeContent,
|
||||
SchemeVibrant,
|
||||
):
|
||||
print("\n" + Scheme.__name__[6:].lower())
|
||||
scheme = Scheme(hct, is_dark, 0.0)
|
||||
|
||||
width, height = image.size
|
||||
opt_width, opt_height = calculate_optimal_size(width, height)
|
||||
if opt_width < width or opt_height < height:
|
||||
image = image.resize((opt_width, opt_height), Image.Resampling.BICUBIC)
|
||||
colours = QuantizeCelebi(list(image.getdata()), 128)
|
||||
colours = {}
|
||||
|
||||
hct = Hct.from_int(Score.score(colours)[0])
|
||||
for color in vars(MaterialDynamicColors).keys():
|
||||
color_name = getattr(MaterialDynamicColors, color)
|
||||
if hasattr(color_name, "get_hct"):
|
||||
colours[color] = color_name.get_hct(scheme).to_rgba()[:3]
|
||||
|
||||
colours = {
|
||||
"primary": colours["primary"],
|
||||
"secondary": colours["secondary"],
|
||||
"tertiary": colours["tertiary"],
|
||||
"text": colours["onBackground"],
|
||||
"subtext1": colours["onSurfaceVariant"],
|
||||
"subtext0": colours["outline"],
|
||||
"overlay2": mix(colours["surface"], colours["outline"], 0.86),
|
||||
"overlay1": mix(colours["surface"], colours["outline"], 0.71),
|
||||
"overlay0": mix(colours["surface"], colours["outline"], 0.57),
|
||||
"surface2": mix(colours["surface"], colours["outline"], 0.43),
|
||||
"surface1": mix(colours["surface"], colours["outline"], 0.29),
|
||||
"surface0": mix(colours["surface"], colours["outline"], 0.14),
|
||||
"base": colours["surface"],
|
||||
"mantle": darken(colours["surface"], 0.03),
|
||||
"crust": darken(colours["surface"], 0.05),
|
||||
}
|
||||
|
||||
if scheme == "fruitsalad":
|
||||
from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad as Scheme
|
||||
elif scheme == "expressive":
|
||||
from materialyoucolor.scheme.scheme_expressive import SchemeExpressive as Scheme
|
||||
elif scheme == "monochrome":
|
||||
from materialyoucolor.scheme.scheme_monochrome import SchemeMonochrome as Scheme
|
||||
elif scheme == "rainbow":
|
||||
from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow as Scheme
|
||||
elif scheme == "tonalspot":
|
||||
from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot as Scheme
|
||||
elif scheme == "neutral":
|
||||
from materialyoucolor.scheme.scheme_neutral import SchemeNeutral as Scheme
|
||||
elif scheme == "fidelity":
|
||||
from materialyoucolor.scheme.scheme_fidelity import SchemeFidelity as Scheme
|
||||
elif scheme == "content":
|
||||
from materialyoucolor.scheme.scheme_content import SchemeContent as Scheme
|
||||
else:
|
||||
from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant as Scheme
|
||||
|
||||
|
||||
scheme = Scheme(hct, is_dark, 0.0)
|
||||
|
||||
|
||||
colours = {}
|
||||
|
||||
for color in vars(MaterialDynamicColors).keys():
|
||||
color_name = getattr(MaterialDynamicColors, color)
|
||||
if hasattr(color_name, "get_hct"):
|
||||
colours[color] = color_name.get_hct(scheme).to_rgba()[0:3]
|
||||
|
||||
colours = {
|
||||
"primary": colours["primary"],
|
||||
"secondary": colours["secondary"],
|
||||
"tertiary": colours["tertiary"],
|
||||
"text": colours["onBackground"],
|
||||
"subtext1": colours["onSurfaceVariant"],
|
||||
"subtext0": colours["outline"],
|
||||
"overlay2": mix(colours["surface"], colours["outline"], 0.86),
|
||||
"overlay1": mix(colours["surface"], colours["outline"], 0.71),
|
||||
"overlay0": mix(colours["surface"], colours["outline"], 0.57),
|
||||
"surface2": mix(colours["surface"], colours["outline"], 0.43),
|
||||
"surface1": mix(colours["surface"], colours["outline"], 0.29),
|
||||
"surface0": mix(colours["surface"], colours["outline"], 0.14),
|
||||
"base": colours["surface"],
|
||||
"mantle": darken(colours["surface"], 0.03),
|
||||
"crust": darken(colours["surface"], 0.05),
|
||||
}
|
||||
|
||||
for name, colour in colours.items():
|
||||
print("{} {:02X}{:02X}{:02X}".format(name, *colour))
|
||||
for name, colour in colours.items():
|
||||
print("{} {:02X}{:02X}{:02X}".format(name, *colour))
|
||||
|
||||
Reference in New Issue
Block a user