from PIL import Image def prepare_tile(tile): """ Convert to mode L and make non-zero pixels 255. """ tile = tile.convert("L") pxa = tile.load() for ty in range(tile.height): for tx in range(tile.width): if pxa[tx, ty] > 16: pxa[tx, ty] = 255 return tile # Colors in wallpaper BRIGHT_GREEN = ( 0, 252, 0) BRIGHT_BLUE = ( 0, 0, 252) BRIGHT_MAGENTA = (255, 0, 255) BRIGHT_CYAN = ( 0, 255, 255) DARK_GREEN = ( 0, 147, 0) def approx_equal(a, b, delta=8): """ Return true if all the components of a and b are within delta. """ return ((abs(a[0] - b[0]) < delta) and (abs(a[1] - b[1]) < delta) and (abs(a[2] - b[2]) < delta)) def get_tile_color(tile): """ Get the ANSI color of a tile. """ pxa = tile.load() for y in range(tile.height): for x in range(tile.width): rgb = pxa[x, y] if approx_equal(rgb, (0, 0, 0)): continue if approx_equal(rgb, BRIGHT_GREEN): return "\x1B[1;92m" elif approx_equal(rgb, DARK_GREEN): return "\x1B[1;32m" elif approx_equal(rgb, BRIGHT_MAGENTA): return "\x1B[1;95m" elif approx_equal(rgb, BRIGHT_CYAN): return "\x1B[1;96m" elif approx_equal(rgb, BRIGHT_BLUE): return "\x1B[1;94m" return "" def main(): OFFSET = (-2, -10) TILE_SIZE = (8, 16) # Load the wallpaper img = Image.open("1670115403069289.png").convert("RGB") # Find all the unique tiles seen_tiles = [] for y in range(OFFSET[1], img.height, TILE_SIZE[1]): for x in range(OFFSET[0], img.width, TILE_SIZE[0]): tile = img.crop((x, y, x+TILE_SIZE[0], y+TILE_SIZE[1])) tile_key = prepare_tile(tile).tobytes() if tile_key not in seen_tiles: seen_tiles.append(tile_key) # (Entered by hand by looking at a saved image made from seen_tiles) CHARS = (' ', '.', '-', ':', '/', '`', '+', 'z', 'o', 'y', 'h', 'a', 'A', 'D', 'N', 'd', "'", 'n') tile_chars = {} for i, c in enumerate(CHARS): tile_key = seen_tiles[i] tile_chars[tile_key] = c output = [] current_line = [] current_color = "" for y in range(OFFSET[1], img.height, TILE_SIZE[1]): for x in range(OFFSET[0], img.width, TILE_SIZE[0]): tile = img.crop((x, y, x+TILE_SIZE[0], y+TILE_SIZE[1])) # Resolve the color color = get_tile_color(tile) if color != current_color: current_line.append(color) current_color = color # Resolve the character tile_key = prepare_tile(tile).tobytes() c = tile_chars[tile_key] current_line.append(c) output.append("".join(current_line)) current_line.clear() # Add the reset color to the last non-empty line for i in range(len(output)-1, -1, -1): line = output[i] if line.strip(): left = line.rstrip() right = line[len(left):] output[i] = "%s\x1B[0m%s" % (left, right) break # Print the output print("\n".join(output)) if __name__ == '__main__': main()