-
-
Save jbboehr/7ffe9c4a582b0ba1131c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import sys | |
| from PIL import Image | |
| xterm256colors = [ # http://pln.jonas.me/xterm-colors | |
| (0, (0x00, 0x00, 0x00)), # SYSTEM | |
| (1, (0x80, 0x00, 0x00)), # SYSTEM | |
| (2, (0x00, 0x80, 0x00)), # SYSTEM | |
| (3, (0x80, 0x80, 0x00)), # SYSTEM | |
| (4, (0x00, 0x00, 0x80)), # SYSTEM | |
| (5, (0x80, 0x00, 0x80)), # SYSTEM | |
| (6, (0x00, 0x80, 0x80)), # SYSTEM | |
| (7, (0xc0, 0xc0, 0xc0)), # SYSTEM | |
| (8, (0x80, 0x80, 0x80)), # SYSTEM | |
| (9, (0xff, 0x00, 0x00)), # SYSTEM | |
| (10, (0x00, 0xff, 0x00)), # SYSTEM | |
| (11, (0xff, 0xff, 0x00)), # SYSTEM | |
| (12, (0x00, 0x00, 0xff)), # SYSTEM | |
| (13, (0xff, 0x00, 0xff)), # SYSTEM | |
| (14, (0x00, 0xff, 0xff)), # SYSTEM | |
| (15, (0xff, 0xff, 0xff)), # SYSTEM | |
| (16, (0x00, 0x00, 0x00)), # Grey0 | |
| (17, (0x00, 0x00, 0x5f)), # NavyBlue | |
| (18, (0x00, 0x00, 0x87)), # DarkBlue | |
| (19, (0x00, 0x00, 0xaf)), # Blue3 | |
| (20, (0x00, 0x00, 0xd7)), # Blue3 | |
| (21, (0x00, 0x00, 0xff)), # Blue1 | |
| (22, (0x00, 0x5f, 0x00)), # DarkGreen | |
| (23, (0x00, 0x5f, 0x5f)), # DeepSkyBlue4 | |
| (24, (0x00, 0x5f, 0x87)), # DeepSkyBlue4 | |
| (25, (0x00, 0x5f, 0xaf)), # DeepSkyBlue4 | |
| (26, (0x00, 0x5f, 0xd7)), # DodgerBlue3 | |
| (27, (0x00, 0x5f, 0xff)), # DodgerBlue2 | |
| (28, (0x00, 0x87, 0x00)), # Green4 | |
| (29, (0x00, 0x87, 0x5f)), # SpringGreen4 | |
| (30, (0x00, 0x87, 0x87)), # Turquoise4 | |
| (31, (0x00, 0x87, 0xaf)), # DeepSkyBlue3 | |
| (32, (0x00, 0x87, 0xd7)), # DeepSkyBlue3 | |
| (33, (0x00, 0x87, 0xff)), # DodgerBlue1 | |
| (34, (0x00, 0xaf, 0x00)), # Green3 | |
| (35, (0x00, 0xaf, 0x5f)), # SpringGreen3 | |
| (36, (0x00, 0xaf, 0x87)), # DarkCyan | |
| (37, (0x00, 0xaf, 0xaf)), # LightSeaGreen | |
| (38, (0x00, 0xaf, 0xd7)), # DeepSkyBlue2 | |
| (39, (0x00, 0xaf, 0xff)), # DeepSkyBlue1 | |
| (40, (0x00, 0xd7, 0x00)), # Green3 | |
| (41, (0x00, 0xd7, 0x5f)), # SpringGreen3 | |
| (42, (0x00, 0xd7, 0x87)), # SpringGreen2 | |
| (43, (0x00, 0xd7, 0xaf)), # Cyan3 | |
| (44, (0x00, 0xd7, 0xd7)), # DarkTurquoise | |
| (45, (0x00, 0xd7, 0xff)), # Turquoise2 | |
| (46, (0x00, 0xff, 0x00)), # Green1 | |
| (47, (0x00, 0xff, 0x5f)), # SpringGreen2 | |
| (48, (0x00, 0xff, 0x87)), # SpringGreen1 | |
| (49, (0x00, 0xff, 0xaf)), # MediumSpringGreen | |
| (50, (0x00, 0xff, 0xd7)), # Cyan2 | |
| (51, (0x00, 0xff, 0xff)), # Cyan1 | |
| (52, (0x5f, 0x00, 0x00)), # DarkRed | |
| (53, (0x5f, 0x00, 0x5f)), # DeepPink4 | |
| (54, (0x5f, 0x00, 0x87)), # Purple4 | |
| (55, (0x5f, 0x00, 0xaf)), # Purple4 | |
| (56, (0x5f, 0x00, 0xd7)), # Purple3 | |
| (57, (0x5f, 0x00, 0xff)), # BlueViolet | |
| (58, (0x5f, 0x5f, 0x00)), # Orange4 | |
| (59, (0x5f, 0x5f, 0x5f)), # Grey37 | |
| (60, (0x5f, 0x5f, 0x87)), # MediumPurple4 | |
| (61, (0x5f, 0x5f, 0xaf)), # SlateBlue3 | |
| (62, (0x5f, 0x5f, 0xd7)), # SlateBlue3 | |
| (63, (0x5f, 0x5f, 0xff)), # RoyalBlue1 | |
| (64, (0x5f, 0x87, 0x00)), # Chartreuse4 | |
| (65, (0x5f, 0x87, 0x5f)), # DarkSeaGreen4 | |
| (66, (0x5f, 0x87, 0x87)), # PaleTurquoise4 | |
| (67, (0x5f, 0x87, 0xaf)), # SteelBlue | |
| (68, (0x5f, 0x87, 0xd7)), # SteelBlue3 | |
| (69, (0x5f, 0x87, 0xff)), # CornflowerBlue | |
| (70, (0x5f, 0xaf, 0x00)), # Chartreuse3 | |
| (71, (0x5f, 0xaf, 0x5f)), # DarkSeaGreen4 | |
| (72, (0x5f, 0xaf, 0x87)), # CadetBlue | |
| (73, (0x5f, 0xaf, 0xaf)), # CadetBlue | |
| (74, (0x5f, 0xaf, 0xd7)), # SkyBlue3 | |
| (75, (0x5f, 0xaf, 0xff)), # SteelBlue1 | |
| (76, (0x5f, 0xd7, 0x00)), # Chartreuse3 | |
| (77, (0x5f, 0xd7, 0x5f)), # PaleGreen3 | |
| (78, (0x5f, 0xd7, 0x87)), # SeaGreen3 | |
| (79, (0x5f, 0xd7, 0xaf)), # Aquamarine3 | |
| (80, (0x5f, 0xd7, 0xd7)), # MediumTurquoise | |
| (81, (0x5f, 0xd7, 0xff)), # SteelBlue1 | |
| (82, (0x5f, 0xff, 0x00)), # Chartreuse2 | |
| (83, (0x5f, 0xff, 0x5f)), # SeaGreen2 | |
| (84, (0x5f, 0xff, 0x87)), # SeaGreen1 | |
| (85, (0x5f, 0xff, 0xaf)), # SeaGreen1 | |
| (86, (0x5f, 0xff, 0xd7)), # Aquamarine1 | |
| (87, (0x5f, 0xff, 0xff)), # DarkSlateGray2 | |
| (88, (0x87, 0x00, 0x00)), # DarkRed | |
| (89, (0x87, 0x00, 0x5f)), # DeepPink4 | |
| (90, (0x87, 0x00, 0x87)), # DarkMagenta | |
| (91, (0x87, 0x00, 0xaf)), # DarkMagenta | |
| (92, (0x87, 0x00, 0xd7)), # DarkViolet | |
| (93, (0x87, 0x00, 0xff)), # Purple | |
| (94, (0x87, 0x5f, 0x00)), # Orange4 | |
| (95, (0x87, 0x5f, 0x5f)), # LightPink4 | |
| (96, (0x87, 0x5f, 0x87)), # Plum4 | |
| (97, (0x87, 0x5f, 0xaf)), # MediumPurple3 | |
| (98, (0x87, 0x5f, 0xd7)), # MediumPurple3 | |
| (99, (0x87, 0x5f, 0xff)), # SlateBlue1 | |
| (100, (0x87, 0x87, 0x00)), # Yellow4 | |
| (101, (0x87, 0x87, 0x5f)), # Wheat4 | |
| (102, (0x87, 0x87, 0x87)), # Grey53 | |
| (103, (0x87, 0x87, 0xaf)), # LightSlateGrey | |
| (104, (0x87, 0x87, 0xd7)), # MediumPurple | |
| (105, (0x87, 0x87, 0xff)), # LightSlateBlue | |
| (106, (0x87, 0xaf, 0x00)), # Yellow4 | |
| (107, (0x87, 0xaf, 0x5f)), # DarkOliveGreen3 | |
| (108, (0x87, 0xaf, 0x87)), # DarkSeaGreen | |
| (109, (0x87, 0xaf, 0xaf)), # LightSkyBlue3 | |
| (110, (0x87, 0xaf, 0xd7)), # LightSkyBlue3 | |
| (111, (0x87, 0xaf, 0xff)), # SkyBlue2 | |
| (112, (0x87, 0xd7, 0x00)), # Chartreuse2 | |
| (113, (0x87, 0xd7, 0x5f)), # DarkOliveGreen3 | |
| (114, (0x87, 0xd7, 0x87)), # PaleGreen3 | |
| (115, (0x87, 0xd7, 0xaf)), # DarkSeaGreen3 | |
| (116, (0x87, 0xd7, 0xd7)), # DarkSlateGray3 | |
| (117, (0x87, 0xd7, 0xff)), # SkyBlue1 | |
| (118, (0x87, 0xff, 0x00)), # Chartreuse1 | |
| (119, (0x87, 0xff, 0x5f)), # LightGreen | |
| (120, (0x87, 0xff, 0x87)), # LightGreen | |
| (121, (0x87, 0xff, 0xaf)), # PaleGreen1 | |
| (122, (0x87, 0xff, 0xd7)), # Aquamarine1 | |
| (123, (0x87, 0xff, 0xff)), # DarkSlateGray1 | |
| (124, (0xaf, 0x00, 0x00)), # Red3 | |
| (125, (0xaf, 0x00, 0x5f)), # DeepPink4 | |
| (126, (0xaf, 0x00, 0x87)), # MediumVioletRed | |
| (127, (0xaf, 0x00, 0xaf)), # Magenta3 | |
| (128, (0xaf, 0x00, 0xd7)), # DarkViolet | |
| (129, (0xaf, 0x00, 0xff)), # Purple | |
| (130, (0xaf, 0x5f, 0x00)), # DarkOrange3 | |
| (131, (0xaf, 0x5f, 0x5f)), # IndianRed | |
| (132, (0xaf, 0x5f, 0x87)), # HotPink3 | |
| (133, (0xaf, 0x5f, 0xaf)), # MediumOrchid3 | |
| (134, (0xaf, 0x5f, 0xd7)), # MediumOrchid | |
| (135, (0xaf, 0x5f, 0xff)), # MediumPurple2 | |
| (136, (0xaf, 0x87, 0x00)), # DarkGoldenrod | |
| (137, (0xaf, 0x87, 0x5f)), # LightSalmon3 | |
| (138, (0xaf, 0x87, 0x87)), # RosyBrown | |
| (139, (0xaf, 0x87, 0xaf)), # Grey63 | |
| (140, (0xaf, 0x87, 0xd7)), # MediumPurple2 | |
| (141, (0xaf, 0x87, 0xff)), # MediumPurple1 | |
| (142, (0xaf, 0xaf, 0x00)), # Gold3 | |
| (143, (0xaf, 0xaf, 0x5f)), # DarkKhaki | |
| (144, (0xaf, 0xaf, 0x87)), # NavajoWhite3 | |
| (145, (0xaf, 0xaf, 0xaf)), # Grey69 | |
| (146, (0xaf, 0xaf, 0xd7)), # LightSteelBlue3 | |
| (147, (0xaf, 0xaf, 0xff)), # LightSteelBlue | |
| (148, (0xaf, 0xd7, 0x00)), # Yellow3 | |
| (149, (0xaf, 0xd7, 0x5f)), # DarkOliveGreen3 | |
| (150, (0xaf, 0xd7, 0x87)), # DarkSeaGreen3 | |
| (151, (0xaf, 0xd7, 0xaf)), # DarkSeaGreen2 | |
| (152, (0xaf, 0xd7, 0xd7)), # LightCyan3 | |
| (153, (0xaf, 0xd7, 0xff)), # LightSkyBlue1 | |
| (154, (0xaf, 0xff, 0x00)), # GreenYellow | |
| (155, (0xaf, 0xff, 0x5f)), # DarkOliveGreen2 | |
| (156, (0xaf, 0xff, 0x87)), # PaleGreen1 | |
| (157, (0xaf, 0xff, 0xaf)), # DarkSeaGreen2 | |
| (158, (0xaf, 0xff, 0xd7)), # DarkSeaGreen1 | |
| (159, (0xaf, 0xff, 0xff)), # PaleTurquoise1 | |
| (160, (0xd7, 0x00, 0x00)), # Red3 | |
| (161, (0xd7, 0x00, 0x5f)), # DeepPink3 | |
| (162, (0xd7, 0x00, 0x87)), # DeepPink3 | |
| (163, (0xd7, 0x00, 0xaf)), # Magenta3 | |
| (164, (0xd7, 0x00, 0xd7)), # Magenta3 | |
| (165, (0xd7, 0x00, 0xff)), # Magenta2 | |
| (166, (0xd7, 0x5f, 0x00)), # DarkOrange3 | |
| (167, (0xd7, 0x5f, 0x5f)), # IndianRed | |
| (168, (0xd7, 0x5f, 0x87)), # HotPink3 | |
| (169, (0xd7, 0x5f, 0xaf)), # HotPink2 | |
| (170, (0xd7, 0x5f, 0xd7)), # Orchid | |
| (171, (0xd7, 0x5f, 0xff)), # MediumOrchid1 | |
| (172, (0xd7, 0x87, 0x00)), # Orange3 | |
| (173, (0xd7, 0x87, 0x5f)), # LightSalmon3 | |
| (174, (0xd7, 0x87, 0x87)), # LightPink3 | |
| (175, (0xd7, 0x87, 0xaf)), # Pink3 | |
| (176, (0xd7, 0x87, 0xd7)), # Plum3 | |
| (177, (0xd7, 0x87, 0xff)), # Violet | |
| (178, (0xd7, 0xaf, 0x00)), # Gold3 | |
| (179, (0xd7, 0xaf, 0x5f)), # LightGoldenrod3 | |
| (180, (0xd7, 0xaf, 0x87)), # Tan | |
| (181, (0xd7, 0xaf, 0xaf)), # MistyRose3 | |
| (182, (0xd7, 0xaf, 0xd7)), # Thistle3 | |
| (183, (0xd7, 0xaf, 0xff)), # Plum2 | |
| (184, (0xd7, 0xd7, 0x00)), # Yellow3 | |
| (185, (0xd7, 0xd7, 0x5f)), # Khaki3 | |
| (186, (0xd7, 0xd7, 0x87)), # LightGoldenrod2 | |
| (187, (0xd7, 0xd7, 0xaf)), # LightYellow3 | |
| (188, (0xd7, 0xd7, 0xd7)), # Grey84 | |
| (189, (0xd7, 0xd7, 0xff)), # LightSteelBlue1 | |
| (190, (0xd7, 0xff, 0x00)), # Yellow2 | |
| (191, (0xd7, 0xff, 0x5f)), # DarkOliveGreen1 | |
| (192, (0xd7, 0xff, 0x87)), # DarkOliveGreen1 | |
| (193, (0xd7, 0xff, 0xaf)), # DarkSeaGreen1 | |
| (194, (0xd7, 0xff, 0xd7)), # Honeydew2 | |
| (195, (0xd7, 0xff, 0xff)), # LightCyan1 | |
| (196, (0xff, 0x00, 0x00)), # Red1 | |
| (197, (0xff, 0x00, 0x5f)), # DeepPink2 | |
| (198, (0xff, 0x00, 0x87)), # DeepPink1 | |
| (199, (0xff, 0x00, 0xaf)), # DeepPink1 | |
| (200, (0xff, 0x00, 0xd7)), # Magenta2 | |
| (201, (0xff, 0x00, 0xff)), # Magenta1 | |
| (202, (0xff, 0x5f, 0x00)), # OrangeRed1 | |
| (203, (0xff, 0x5f, 0x5f)), # IndianRed1 | |
| (204, (0xff, 0x5f, 0x87)), # IndianRed1 | |
| (205, (0xff, 0x5f, 0xaf)), # HotPink | |
| (206, (0xff, 0x5f, 0xd7)), # HotPink | |
| (207, (0xff, 0x5f, 0xff)), # MediumOrchid1 | |
| (208, (0xff, 0x87, 0x00)), # DarkOrange | |
| (209, (0xff, 0x87, 0x5f)), # Salmon1 | |
| (210, (0xff, 0x87, 0x87)), # LightCoral | |
| (211, (0xff, 0x87, 0xaf)), # PaleVioletRed1 | |
| (212, (0xff, 0x87, 0xd7)), # Orchid2 | |
| (213, (0xff, 0x87, 0xff)), # Orchid1 | |
| (214, (0xff, 0xaf, 0x00)), # Orange1 | |
| (215, (0xff, 0xaf, 0x5f)), # SandyBrown | |
| (216, (0xff, 0xaf, 0x87)), # LightSalmon1 | |
| (217, (0xff, 0xaf, 0xaf)), # LightPink1 | |
| (218, (0xff, 0xaf, 0xd7)), # Pink1 | |
| (219, (0xff, 0xaf, 0xff)), # Plum1 | |
| (220, (0xff, 0xd7, 0x00)), # Gold1 | |
| (221, (0xff, 0xd7, 0x5f)), # LightGoldenrod2 | |
| (222, (0xff, 0xd7, 0x87)), # LightGoldenrod2 | |
| (223, (0xff, 0xd7, 0xaf)), # NavajoWhite1 | |
| (224, (0xff, 0xd7, 0xd7)), # MistyRose1 | |
| (225, (0xff, 0xd7, 0xff)), # Thistle1 | |
| (226, (0xff, 0xff, 0x00)), # Yellow1 | |
| (227, (0xff, 0xff, 0x5f)), # LightGoldenrod1 | |
| (228, (0xff, 0xff, 0x87)), # Khaki1 | |
| (229, (0xff, 0xff, 0xaf)), # Wheat1 | |
| (230, (0xff, 0xff, 0xd7)), # Cornsilk1 | |
| (231, (0xff, 0xff, 0xff)), # Grey100 | |
| (232, (0x08, 0x08, 0x08)), # Grey3 | |
| (233, (0x12, 0x12, 0x12)), # Grey7 | |
| (234, (0x1c, 0x1c, 0x1c)), # Grey11 | |
| (235, (0x26, 0x26, 0x26)), # Grey15 | |
| (236, (0x30, 0x30, 0x30)), # Grey19 | |
| (237, (0x3a, 0x3a, 0x3a)), # Grey23 | |
| (238, (0x44, 0x44, 0x44)), # Grey27 | |
| (239, (0x4e, 0x4e, 0x4e)), # Grey30 | |
| (240, (0x58, 0x58, 0x58)), # Grey35 | |
| (241, (0x62, 0x62, 0x62)), # Grey39 | |
| (242, (0x6c, 0x6c, 0x6c)), # Grey42 | |
| (243, (0x76, 0x76, 0x76)), # Grey46 | |
| (244, (0x80, 0x80, 0x80)), # Grey50 | |
| (245, (0x8a, 0x8a, 0x8a)), # Grey54 | |
| (246, (0x94, 0x94, 0x94)), # Grey58 | |
| (247, (0x9e, 0x9e, 0x9e)), # Grey62 | |
| (248, (0xa8, 0xa8, 0xa8)), # Grey66 | |
| (249, (0xb2, 0xb2, 0xb2)), # Grey70 | |
| (250, (0xbc, 0xbc, 0xbc)), # Grey74 | |
| (251, (0xc6, 0xc6, 0xc6)), # Grey78 | |
| (252, (0xd0, 0xd0, 0xd0)), # Grey82 | |
| (253, (0xda, 0xda, 0xda)), # Grey85 | |
| (254, (0xe4, 0xe4, 0xe4)), # Grey89 | |
| (255, (0xee, 0xee, 0xee)), # Grey93 | |
| ] | |
| def colordiff(ca, cb): | |
| return ( | |
| abs(ca[0] - cb[0]) + | |
| abs(ca[1] - cb[1]) + | |
| abs(ca[2] - cb[2]) | |
| ) | |
| def find_colorcode(c): | |
| winning_colordiff = 999 | |
| winning_colorcode = -1 | |
| for cc in xterm256colors: | |
| cdiff = colordiff(c, cc[1]) | |
| if cdiff < winning_colordiff: | |
| winning_colordiff = cdiff | |
| winning_colorcode = cc[0] | |
| return winning_colorcode | |
| if len(sys.argv) <= 2: | |
| print("Usage: %s <image file> <text file>" % sys.argv[0]) | |
| print("Converts images into color sequences (xterm-256color)") | |
| exit(1) | |
| img = Image.open(sys.argv[1]) | |
| if img.size[0] * img.size[1] > 120 * 36: | |
| print("Warning: Big image, did you forget to scale it down?") | |
| img = img.convert("RGB") | |
| imgd = img.load() | |
| tf = open(sys.argv[2], "wb") | |
| for y in range(img.size[1]): | |
| lastcc = -1 | |
| for x in range(img.size[0]): | |
| cc = find_colorcode(imgd[x, y]) | |
| if cc == lastcc: | |
| tf.write(b" ") # Just add more spaces instead of repeating the ANSI sequence | |
| else: | |
| tf.write(b"\x1b[48;5;" + str(cc).encode("ascii") + b"m ") # 2 spaces per pixel because chars are non-square | |
| lastcc = cc | |
| tf.write(b"\x1b[0m\n") | |
| tf.flush() | |
| tf.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment