diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/color_engine.py | 71 | ||||
| -rw-r--r-- | src/get_args.py | 13 | ||||
| -rw-r--r-- | src/instant_rice.py | 6 | ||||
| -rw-r--r-- | src/load_config.py | 13 | ||||
| -rw-r--r-- | src/paths.py | 7 | ||||
| -rw-r--r-- | src/user_interface.py | 58 |
6 files changed, 119 insertions, 49 deletions
diff --git a/src/color_engine.py b/src/color_engine.py index 1b94a02..fb885a8 100644 --- a/src/color_engine.py +++ b/src/color_engine.py @@ -10,7 +10,6 @@ def grabColors(img_path: str, num_colors: int) -> list(): """ img = cv.imread(img_path) img = cv.cvtColor(img, cv.COLOR_BGR2RGB) - # scale image down by factor of 10 to decrease computation time dim = (int(len(img[0])/10), int(len(img)/10)) img = cv.resize(img, dim, interpolation= cv.INTER_AREA) @@ -20,6 +19,58 @@ def grabColors(img_path: str, num_colors: int) -> list(): clt.fit(img.reshape(-1, 3)) return clt.cluster_centers_ +def compColors(color_list: list) -> list: + """ + given a list of colors, generate complimentary colors to contrast the prominent colors. + return a list of these colors. + """ + compliments = [] + for color in color_list: + curr_hex = color[1:] # slice off the # from the hex code + rgb = (curr_hex[0:2], curr_hex[2:4], curr_hex[4:6]) + comp = ['%02X' % (255 - int(a, 16)) for a in rgb] # magic :D + compliments.append('#' + ''.join(comp)) + return compliments + +def checkContrast(hex_color_list: list, hex_compliment_list: list) -> list(): + """ + Given the list of colors and their compliments, reutrn a list of the contrast values + between the colors + """ + color_list = hexToRGB_list(hex_color_list) + compliment_list = hexToRGB_list(hex_compliment_list) + contrast_values = [] + + for i, color in enumerate(color_list): + compliment = compliment_list[i] + + # determine relative luminance of each color + color_luminence = relativeLuminance(color) + compliment_luminence = relativeLuminance(compliment) + value = (max(color_luminence, compliment_luminence) + 0.05) / (min(color_luminence, compliment_luminence) + 0.05) + contrast_values.append(value) + return contrast_values + + +def relativeLuminance(color: list): + + threshold = 0.03928 # this whole function is magic constants lol + channels = [] + + for channel in color: + channel_norm = channel / 255 + if channel_norm <= threshold: + channels.append(channel_norm / 12.92) + else: + channel_val = ((channel_norm + 0.055) / 1.055)**(2.4) + channels.append(channel_val) + + red, green, blue = channels + luminance = (0.2126 * red) + (0.7152 * green) + (0.0722 * blue) + return luminance + + + def rgbToHex(input_values: list) -> list: """ Takes in a list of RBG color values and returns a list of those same colors as hex values @@ -39,16 +90,10 @@ def hexToRGB(hex_value: str) -> tuple: hex_value = hex_value.lstrip('#') return tuple(int(hex_value[i:i+2], 16) for i in (0, 2, 4)) # Magic :DDDDDD -def compColors(color_list: list) -> list: - """ - given a list of colors, generate complimentary colors to contrast the prominent colors. - return a list of these colors. - """ - compliments = [] - for color in color_list: - curr_hex = color[1:] # slice off the # from the hex code - rgb = (curr_hex[0:2], curr_hex[2:4], curr_hex[4:6]) - comp = ['%02X' % (255 - int(a, 16)) for a in rgb] # magic :D - compliments.append('#' + ''.join(comp)) - return compliments +def hexToRGB_list(hex_list: list) -> list: + colors = [] + for color in hex_list: + hex_value = color.lstrip('#') + colors.append(tuple(int(hex_value[i:i+2], 16) for i in (0, 2, 4))) # Magic :DDDDDD + return colors diff --git a/src/get_args.py b/src/get_args.py index 09c5279..ade7740 100644 --- a/src/get_args.py +++ b/src/get_args.py @@ -1,27 +1,20 @@ import user_interface import os -def get_args(args) -> tuple: +def get_args(args, walls_dir) -> tuple: # arguments that can be passed into program - dmenu = False - nolock = False initialize = False reconfigure = False - nolock = False if '-r' in args: - img_path = user_interface.pickRandomWallpaper() + img_path = user_interface.pickRandomWallpaper(walls_dir) else: img_path = f"{os.getcwd()}/{args[1]}" if '--initialize' in args: initialize = True if '--reconfigure' in args: reconfigure = True - if '--dmenu' in args: - dmenu = True - if '--nolock' in args: - nolock = True - return img_path, dmenu, nolock, initialize, reconfigure + return img_path, initialize, reconfigure def usage(args) -> None: print(f""" diff --git a/src/instant_rice.py b/src/instant_rice.py index a42ec0f..5076a6b 100644 --- a/src/instant_rice.py +++ b/src/instant_rice.py @@ -9,14 +9,14 @@ from load_config import systemConfig if __name__ == '__main__': if len(sys.argv) > 1: - img_path, update_dmenu, nolock, initialize, reconfigure = get_args(sys.argv) - hex_colors, hex_compliments = user_interface.colorPickerUI(img_path) config = systemConfig() + img_path, initialize, reconfigure = get_args(sys.argv, config.wallpaper_directory) + hex_colors, hex_compliments = user_interface.colorPickerUI(img_path, config.num_palettes) if config.polybar_config != "": update_polybar.updatePolybarTheme(config.polybar_config, hex_colors, hex_compliments) if config.rofi_config != "": update_rofi.updateRofiTheme(config.rofi_config, hex_colors, hex_compliments) if config.i3_config: - update_i3.updatei3Theme(config.i3_config, img_path, hex_colors, hex_compliments, nolock, config.use_dmenu, config.i3_lock_image) + update_i3.updatei3Theme(config.i3_config, img_path, hex_colors, hex_compliments, config.generate_i3_lock, config.use_dmenu, config.i3_lock_image) else: usage(sys.argv) diff --git a/src/load_config.py b/src/load_config.py index 2c894a3..dbc0d81 100644 --- a/src/load_config.py +++ b/src/load_config.py @@ -16,8 +16,8 @@ class systemConfig: rofi_config = "" username = "" rice_config = "" - #instant rice configuration settings + num_palettes = 15 use_dmenu = False generate_i3_lock = False @@ -69,5 +69,14 @@ class systemConfig: match = line.split(' ') self.generate_i3_lock = True if match[2] == 'True' else False if "wallpaper_directory" in line: - match = line.split(' ') + match = line.strip().split(' ') + if not match[2].endswith('/'): + match[2] += '/' self.wallpaper_directory = match[2] + if "num_palettes" in line: + match = line.strip().split(' ') + if match[2].isdigit(): + self.num_palettes = int(match[2]) + else: + print(f'Invalid configuration parameter at line {i}:\n{line}.\nUsing default \ + configuration of 15 palettes.') diff --git a/src/paths.py b/src/paths.py deleted file mode 100644 index b4cf3d5..0000000 --- a/src/paths.py +++ /dev/null @@ -1,7 +0,0 @@ -Paths = { - 'i3': '/home/chandler/.config/i3/config', - 'polybar': '/home/chandler/.config/polybar/config.ini', - 'wallpapers': '/home/chandler/Pictures/papes/', - 'lockscreen': '/home/chandler/.config/i3/', - 'rofi': '/home/chandler/.config/rofi/theme.rasi' - } diff --git a/src/user_interface.py b/src/user_interface.py index f3d068a..12014a6 100644 --- a/src/user_interface.py +++ b/src/user_interface.py @@ -1,19 +1,25 @@ import os import random -from paths import Paths + import color_engine from rich import print -def colorPickerUI(img_path: str) -> tuple: +def colorPickerUI(img_path: str, num_palettes: int) -> tuple: #display the selected color scheme and ask user if they like it or want to generate a new color scheme + hex_colors, hex_compliments = selectPalette(img_path, num_palettes) + final_colors, final_compliments = selectColorsFromPalette(hex_colors, hex_compliments) + return final_colors, final_compliments + +def selectPalette(img_path: str, num_palettes: int) -> tuple: + # confirmed = False while not confirmed: print() - popularColors = color_engine.grabColors(img_path, 3) + popularColors = color_engine.grabColors(img_path, num_palettes) hex_colors = color_engine.rgbToHex(popularColors) hex_compliments = color_engine.compColors(hex_colors) - + constrast_levels = color_engine.checkContrast(hex_colors, hex_compliments) main_colors = '' complimentary_colors = '' @@ -22,29 +28,53 @@ def colorPickerUI(img_path: str) -> tuple: print(main_colors) for color in hex_compliments: complimentary_colors += f'[on {color}] [/on {color}]' - print(complimentary_colors) - print() + print(complimentary_colors, '\n') count = 0 for i in range(len(hex_colors)): - print(f'[{hex_compliments[i]} on {hex_colors[i]}]\tGenerated Color Scheme\t\t ({count})') + print(f'[{hex_compliments[i]} on {hex_colors[i]}]\tGenerated Color Scheme\t\t ({count})', f'contrast: {constrast_levels[i]}') count += 1 - print('[bold](a)ccept (r)etry') + print('[bold](a)ccept palette (g)enerate new palette') response = input('> ') - if response == 'r': - continue - else: + if response == 'a': confirmed = True + print('[bold green]Palette Confirmed!') + else: + continue + return hex_colors, hex_compliments -def pickRandomWallpaper() -> str: +def selectColorsFromPalette(hex_colors, hex_compliments): + selected = False + while not selected: + print('[bold blue]Select top 3 colors from list in order Primary, Secondary, Accent (IE, "4 10 6")') + selectedColors = input("> ") + selectedColors = selectedColors.split() + all_digits = all(i.isdigit() for i in selectedColors) + if all_digits: + selected = True + else: + print('[bold red]Invalid selection. Use positive integers corresponding to color pair to select.') + continue + + selectedColors = [int(i) for i in selectedColors] + final_colors = [] + final_compliments = [] + + for selection in selectedColors: + final_colors.append(hex_colors[selection]) + final_compliments.append(hex_compliments[selection]) + + return final_colors, final_compliments + +def pickRandomWallpaper(walls_dir) -> str: confirmed = False history = [] - num_wallpapers = len(os.listdir(Paths['wallpapers'])) + num_wallpapers = len(os.listdir(walls_dir)) while not confirmed: if len(history) == num_wallpapers: print('[bold blue] Wallpapers exhausted. Resetting history...') history.clear() - wallpaper = Paths['wallpapers'] + random.choice(os.listdir(Paths['wallpapers'])) + wallpaper = walls_dir + random.choice(os.listdir(walls_dir)) if wallpaper in history: continue history.append(wallpaper) |
