Skip to content

Instantly share code, notes, and snippets.

@jbboehr
Forked from sfan5/image2xterm.py
Last active August 29, 2015 14:14
Show Gist options
  • Save jbboehr/7ffe9c4a582b0ba1131c to your computer and use it in GitHub Desktop.
Save jbboehr/7ffe9c4a582b0ba1131c to your computer and use it in GitHub Desktop.
#!/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