import cv2 as cv from sklearn.cluster import KMeans def grabColors(img_path: str, num_colors: int) -> list: """ Takes in an image, and Number of colors, then returns a list of those colors. The list of colors will contain the most prominent colors present in the image. img_path - the path where your image lives (IE, /home/chandler/Pictures/moss.png) num_colors - the number of colors you need back from the image """ 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) clt = KMeans(n_clusters=num_colors, n_init='auto') 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:] rgb = (curr_hex[0:2], curr_hex[2:4], curr_hex[4:6]) comp = ['%02X' % (255 - int(a, 16)) for a in rgb] 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) -> float: """ Determines the luminance of color. The luminance allows us to compute the contrast between two colors by comparing their relative luminance. The magic constants in this function are all taken from the following description of relative luminance: https://www.w3.org/TR/WCAG20/#relativeluminancedef """ threshold = 0.03928 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 """ hex_list=[] for color in input_values: red = int(color[0]) green = int(color[1]) blue = int(color[2]) hex_list.append('#{:02x}{:02x}{:02x}'.format(red, green, blue)) return hex_list def hexToRGB(hex_value: str) -> tuple: """ Takes in a list of Hex values and returns a tuple of those colors as rgb values """ hex_value = hex_value.lstrip('#') return tuple(int(hex_value[i:i+2], 16) for i in (0, 2, 4)) 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))) return colors