Enhance blob_color_fixer to check and boost saturation for bland palettes

This commit is contained in:
2026-04-20 17:58:49 -04:00
parent b98ddd3db9
commit b2717d88e8
+45 -21
View File
@@ -9,28 +9,37 @@ def hex_to_rgb(hex_str):
def rgb_to_hex(r, g, b): def rgb_to_hex(r, g, b):
return '#{:02x}{:02x}{:02x}'.format(int(r * 255), int(g * 255), int(b * 255)) return '#{:02x}{:02x}{:02x}'.format(int(r * 255), int(g * 255), int(b * 255))
def shift_hue(hex_str, shift_amount): def shift_hue_and_saturate(hex_str, shift_amount):
r, g, b = hex_to_rgb(hex_str) r, g, b = hex_to_rgb(hex_str)
h, l, s = colorsys.rgb_to_hls(r, g, b) h, l, s = colorsys.rgb_to_hls(r, g, b)
h = (h + shift_amount) % 1.0 h = (h + shift_amount) % 1.0
s = max(s, 0.65) # Force vibrancy
l = min(max(l, 0.4), 0.7) # Ensure it's not too dark or overly washed out
r, g, b = colorsys.hls_to_rgb(h, l, s) r, g, b = colorsys.hls_to_rgb(h, l, s)
return rgb_to_hex(r, g, b) return rgb_to_hex(r, g, b)
def get_hues(hex_list): def get_hls_stats(hex_list):
hues = [] hues = []
sats = []
for hex_str in hex_list: for hex_str in hex_list:
r, g, b = hex_to_rgb(hex_str) r, g, b = hex_to_rgb(hex_str)
h, l, s = colorsys.rgb_to_hls(r, g, b) h, l, s = colorsys.rgb_to_hls(r, g, b)
hues.append(h) hues.append(h)
return hues sats.append(s)
return hues, sats
def is_monotone(hues, threshold=0.1): def is_monotone_or_bland(hues, sats, hue_threshold=0.15, sat_threshold=0.35):
# Calculate the maximum distance between any two hues on the color wheel if not hues or not sats: return False
if not hues: return False
# Calculate hue variance
min_h = min(hues) min_h = min(hues)
max_h = max(hues) max_h = max(hues)
diff = min(max_h - min_h, 1.0 - (max_h - min_h)) hue_diff = min(max_h - min_h, 1.0 - (max_h - min_h))
return diff < threshold
# Calculate average saturation
avg_s = sum(sats) / len(sats)
return hue_diff < hue_threshold or avg_s < sat_threshold
def main(): def main():
if len(sys.argv) < 2: if len(sys.argv) < 2:
@@ -50,22 +59,37 @@ def main():
print("Not enough colors found in file.") print("Not enough colors found in file.")
sys.exit(1) sys.exit(1)
# Check hue variance of accent colors (indices 1-6) # Check hue variance and saturation of accent colors (indices 1-6)
accents = colors[1:7] accents = colors[1:7]
hues = get_hues(accents) hues, sats = get_hls_stats(accents)
if is_monotone(hues, 0.15): if is_monotone_or_bland(hues, sats, hue_threshold=0.15, sat_threshold=0.35):
print("Detected monotone palette. Generating vibrant complementary colors...") print("Detected monotone or bland palette. Generating vibrant complementary colors...")
base_accent = accents[-1] # Usually the last accent is the brightest
# Generate new colors # Pick the most saturated accent as the base
comp = shift_hue(base_accent, 0.5) base_accent = accents[-1]
ana1 = shift_hue(base_accent, 0.083) max_sat = 0
ana2 = shift_hue(base_accent, -0.083) for i, sat in enumerate(sats):
split1 = shift_hue(base_accent, 0.416) if sat > max_sat:
split2 = shift_hue(base_accent, -0.416) max_sat = sat
base_accent = accents[i]
new_accents = [base_accent, comp, ana1, ana2, split1, split2] # Generate new colors with forced vibrancy
comp = shift_hue_and_saturate(base_accent, 0.5)
ana1 = shift_hue_and_saturate(base_accent, 0.083)
ana2 = shift_hue_and_saturate(base_accent, -0.083)
split1 = shift_hue_and_saturate(base_accent, 0.416)
split2 = shift_hue_and_saturate(base_accent, -0.416)
# The base accent itself also gets saturated if it was too bland
r, g, b = hex_to_rgb(base_accent)
h, l, s = colorsys.rgb_to_hls(r, g, b)
if s < 0.65:
base_vibrant = shift_hue_and_saturate(base_accent, 0.0)
else:
base_vibrant = base_accent
new_accents = [base_vibrant, comp, ana1, ana2, split1, split2]
# Replace normal and bright accents # Replace normal and bright accents
for i in range(6): for i in range(6):
@@ -77,7 +101,7 @@ def main():
f.write(f"{color}\n") f.write(f"{color}\n")
print("Colors successfully enhanced.") print("Colors successfully enhanced.")
else: else:
print("Palette is already diverse enough.") print("Palette is already vibrant and diverse enough.")
if __name__ == "__main__": if __name__ == "__main__":
main() main()