"""Named RGB palettes for pixel_art() and pixel_art_video(). Palette RGB values sourced from pixel-art-studio (MIT License) https://github.com/Synero/pixel-art-studio — see ATTRIBUTION.md. """ PALETTES = { # ── Hardware palettes ─────────────────────────────────────────────── "NES": [ (0, 0, 0), (124, 124, 124), (0, 0, 252), (0, 0, 188), (68, 40, 188), (148, 0, 132), (168, 0, 32), (168, 16, 0), (136, 20, 0), (0, 116, 0), (0, 148, 0), (0, 120, 0), (0, 88, 0), (0, 64, 88), (188, 188, 188), (0, 120, 248), (0, 88, 248), (104, 68, 252), (216, 0, 204), (228, 0, 88), (248, 56, 0), (228, 92, 16), (172, 124, 0), (0, 184, 0), (0, 168, 0), (0, 168, 68), (0, 136, 136), (248, 248, 248), (60, 188, 252), (104, 136, 252), (152, 120, 248), (248, 120, 248), (248, 88, 152), (248, 120, 88), (252, 160, 68), (248, 184, 0), (184, 248, 24), (88, 216, 84), (88, 248, 152), (0, 232, 216), (120, 120, 120), (252, 252, 252), (164, 228, 252), (184, 184, 248), (216, 184, 248), (248, 184, 248), (248, 164, 192), (240, 208, 176), (252, 224, 168), (248, 216, 120), (216, 248, 120), (184, 248, 184), (184, 248, 216), (0, 252, 252), (216, 216, 216), ], "C64": [ (0, 0, 0), (255, 255, 255), (161, 77, 67), (106, 191, 199), (161, 87, 164), (92, 172, 95), (64, 64, 223), (191, 206, 137), (161, 104, 60), (108, 80, 21), (203, 126, 117), (98, 98, 98), (137, 137, 137), (154, 226, 155), (124, 124, 255), (173, 173, 173), ], "COMMODORE_64": [ (0, 0, 0), (255, 255, 255), (161, 77, 67), (106, 192, 200), (161, 87, 165), (92, 172, 95), (64, 68, 227), (203, 214, 137), (163, 104, 58), (110, 84, 11), (204, 127, 118), (99, 99, 99), (139, 139, 139), (154, 227, 157), (139, 127, 205), (175, 175, 175), ], "ZX_SPECTRUM": [ (0, 0, 0), (0, 39, 251), (252, 48, 22), (255, 63, 252), (0, 249, 44), (0, 252, 254), (255, 253, 51), (255, 255, 255), ], "APPLE_II_LO": [ (0, 0, 0), (133, 59, 81), (80, 71, 137), (234, 93, 240), (0, 104, 82), (146, 146, 146), (0, 168, 241), (202, 195, 248), (81, 92, 15), (235, 127, 35), (146, 146, 146), (246, 185, 202), (0, 202, 41), (203, 211, 155), (155, 220, 203), (255, 255, 255), ], "APPLE_II_HI": [ (0, 0, 0), (255, 0, 255), (0, 255, 0), (255, 255, 255), (0, 175, 255), (255, 80, 0), ], "GAMEBOY_ORIGINAL": [ (0, 63, 0), (46, 115, 32), (140, 191, 10), (160, 207, 10), ], "GAMEBOY_POCKET": [ (0, 0, 0), (85, 85, 85), (170, 170, 170), (255, 255, 255), ], "GAMEBOY_VIRTUALBOY": [ (239, 0, 0), (164, 0, 0), (85, 0, 0), (0, 0, 0), ], "PICO_8": [ (0, 0, 0), (29, 43, 83), (126, 37, 83), (0, 135, 81), (171, 82, 54), (95, 87, 79), (194, 195, 199), (255, 241, 232), (255, 0, 77), (255, 163, 0), (255, 236, 39), (0, 228, 54), (41, 173, 255), (131, 118, 156), (255, 119, 168), (255, 204, 170), ], "TELETEXT": [ (0, 0, 0), (255, 0, 0), (0, 128, 0), (255, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255), (255, 255, 255), ], "CGA_MODE4_PAL1": [ (0, 0, 0), (255, 255, 255), (0, 255, 255), (255, 0, 255), ], "MSX": [ (0, 0, 0), (62, 184, 73), (116, 208, 125), (89, 85, 224), (128, 118, 241), (185, 94, 81), (101, 219, 239), (219, 101, 89), (255, 137, 125), (204, 195, 94), (222, 208, 135), (58, 162, 65), (183, 102, 181), (204, 204, 204), (255, 255, 255), ], "MICROSOFT_WINDOWS_16": [ (0, 0, 0), (128, 0, 0), (0, 128, 0), (128, 128, 0), (0, 0, 128), (128, 0, 128), (0, 128, 128), (192, 192, 192), (128, 128, 128), (255, 0, 0), (0, 255, 0), (255, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255), (255, 255, 255), ], "MICROSOFT_WINDOWS_PAINT": [ (0, 0, 0), (255, 255, 255), (123, 123, 123), (189, 189, 189), (123, 12, 2), (255, 37, 0), (123, 123, 2), (255, 251, 2), (0, 123, 2), (2, 249, 2), (0, 123, 122), (2, 253, 254), (2, 19, 122), (5, 50, 255), (123, 25, 122), (255, 64, 254), (122, 57, 2), (255, 122, 57), (123, 123, 56), (255, 252, 122), (2, 57, 57), (5, 250, 123), (0, 123, 255), (255, 44, 123), ], "MONO_BW": [(0, 0, 0), (255, 255, 255)], "MONO_AMBER": [(40, 40, 40), (255, 176, 0)], "MONO_GREEN": [(40, 40, 40), (51, 255, 51)], # ── Artistic palettes ─────────────────────────────────────────────── "PASTEL_DREAM": [ (255, 218, 233), (255, 229, 204), (255, 255, 204), (204, 255, 229), (204, 229, 255), (229, 204, 255), (255, 204, 229), (204, 255, 255), (255, 245, 220), (230, 230, 250), ], "NEON_CYBER": [ (0, 0, 0), (255, 0, 128), (0, 255, 255), (255, 0, 255), (0, 255, 128), (255, 255, 0), (128, 0, 255), (255, 128, 0), (0, 128, 255), (255, 255, 255), ], "RETRO_WARM": [ (62, 39, 35), (139, 69, 19), (210, 105, 30), (244, 164, 96), (255, 218, 185), (255, 245, 238), (178, 34, 34), (205, 92, 92), (255, 99, 71), (255, 160, 122), ], "OCEAN_DEEP": [ (0, 25, 51), (0, 51, 102), (0, 76, 153), (0, 102, 178), (0, 128, 204), (51, 153, 204), (102, 178, 204), (153, 204, 229), (204, 229, 255), (229, 245, 255), ], "FOREST_MOSS": [ (34, 51, 34), (51, 76, 51), (68, 102, 51), (85, 128, 68), (102, 153, 85), (136, 170, 102), (170, 196, 136), (204, 221, 170), (238, 238, 204), (245, 245, 220), ], "SUNSET_FIRE": [ (51, 0, 0), (102, 0, 0), (153, 0, 0), (204, 0, 0), (255, 0, 0), (255, 51, 0), (255, 102, 0), (255, 153, 0), (255, 204, 0), (255, 255, 51), ], "ARCTIC_ICE": [ (0, 0, 51), (0, 0, 102), (0, 51, 153), (0, 102, 153), (51, 153, 204), (102, 204, 255), (153, 229, 255), (204, 242, 255), (229, 247, 255), (255, 255, 255), ], "VINTAGE_ROSE": [ (103, 58, 63), (137, 72, 81), (170, 91, 102), (196, 113, 122), (219, 139, 147), (232, 168, 175), (240, 196, 199), (245, 215, 217), (249, 232, 233), (255, 245, 245), ], "EARTH_CLAY": [ (62, 39, 35), (89, 56, 47), (116, 73, 59), (143, 90, 71), (170, 107, 83), (197, 124, 95), (210, 155, 126), (222, 186, 160), (235, 217, 196), (248, 248, 232), ], "ELECTRIC_VIOLET": [ (26, 0, 51), (51, 0, 102), (76, 0, 153), (102, 0, 204), (128, 0, 255), (153, 51, 255), (178, 102, 255), (204, 153, 255), (229, 204, 255), (245, 229, 255), ], } def build_palette_image(palette_name): """Build a 1x1 PIL 'P'-mode image with the named palette for Image.quantize(palette=...).""" from PIL import Image if palette_name not in PALETTES: raise ValueError( f"Unknown palette {palette_name!r}. " f"Choose from: {sorted(PALETTES)}" ) flat = [] for (r, g, b) in PALETTES[palette_name]: flat.extend([r, g, b]) # Pad to 768 bytes (256 colors) as PIL requires while len(flat) < 768: flat.append(0) pal_img = Image.new("P", (1, 1)) pal_img.putpalette(flat) return pal_img