diff --git a/blocked.png b/blocked.png new file mode 100644 index 0000000..596e43f Binary files /dev/null and b/blocked.png differ diff --git a/two-tone.py b/two-tone.py index c5ead60..e9f4603 100644 --- a/two-tone.py +++ b/two-tone.py @@ -44,15 +44,21 @@ def choose_color_pair_kmeans(counts: dict[RGB,int]) -> tuple[RGB, RGB]: def weighted_avg(colors: list[RGB]) -> RGB: result = [0, 0, 0] + total_weight = 0 for color in colors: weight = counts[color] + total_weight += weight for i in range(3): result[i] += weight*color[i] - return tuple(round(x/total_count) for x in result) + if total_weight == 0: + total_weight += 1 # Hack to handle division-by-zero + return tuple(round(x/total_weight) for x in result) # k-means to choose the two colors old_result = (None, None) - result = (darkest_color, lightest_color) + result = (min(colors, key=brightness), max(colors, key=brightness)) + print(f"k-means using {counts=}") + print(f"starting value: {result}") while True: lists = ([], []) for color in colors: @@ -63,7 +69,9 @@ def choose_color_pair_kmeans(counts: dict[RGB,int]) -> tuple[RGB, RGB]: else: lists[1].append(color) old_result = result + print(f"{lists=}") result = tuple(weighted_avg(cs) for cs in lists) + print(f"updated: {result}") if old_result == result: break return tuple(nearest_color(x, palette) for x in result) @@ -119,7 +127,10 @@ def two_tone(img: Image, xy1: tuple[int,int] = None, xy2: tuple[int,int] = None) if color not in counts: counts[color] = 0 counts[color] += 1 - dark, light = choose_color_pair_luminance(counts) + #dark, light = choose_color_pair_luminance(counts) + print(f"choosing color pair for {xy1=}") + dark, light = choose_color_pair_kmeans(counts) + print(f"final: {dark=}, {light=}\n") if light == None: # Only one color, *ought* to be a no-op light = dark @@ -138,3 +149,7 @@ blocked = img.copy() for x in range(0, img.width, BLOCK_SIZE): for y in range(0, img.height, BLOCK_SIZE): two_tone(blocked, (x, y), (x + BLOCK_SIZE, y + BLOCK_SIZE)) +blocked.save("blocked.png") +for x in range(5): + for y in range(5): + blocked.putpixel((x, y), 0)