Last active
July 13, 2020 18:24
-
-
Save sfan5/2d971a5a087881a966c3 to your computer and use it in GitHub Desktop.
Converts images into color sequences (xterm-256color)
This file contains 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 | |
import getopt | |
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 | |
] | |
class StdoutWrapper(): | |
def write(f, b): | |
sys.stdout.write(b.decode('utf-8')) | |
def flush(f): | |
sys.stdout.flush() | |
def close(f): | |
return | |
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 | |
def ctrl_fg(cc): | |
if cc == -1: | |
return b"\x1b[39m" | |
else: | |
return b"\x1b[38;5;" + str(cc).encode("ascii") + b"m" | |
def ctrl_bg(cc): | |
if cc == -1: | |
return b"\x1b[49m" | |
else: | |
return b"\x1b[48;5;" + str(cc).encode("ascii") + b"m" | |
try: | |
opts, args = getopt.getopt(sys.argv[1:], "o:ua", ["unicode-compat"]) | |
except getopt.GetoptError as e: | |
print(str(e)) | |
exit(1) | |
if len(args) < 1: | |
print("Usage: %s [-o FILENAME] [-u] [--unicode-compat] [-a] FILENAME" % sys.argv[0]) | |
print("Converts images into color sequences (xterm-256color)") | |
print("\t-o FILENAME\t\tWrite color sequences to file instead of outputting to stdout") | |
print("\t-u\t\t\tUse unicode characters (U+2584 and U+2580) to allow 2x resolution on the same space") | |
print("\t--unicode-compat\tTry to be more compatible to terminals that are not xterm") | |
print("\t\t\t\tUse this if it doesn't look like right") | |
print("\t-a\t\t\tUse alpha channel of image") | |
exit(1) | |
if len(args) > 1: | |
print("Too many arguments.") | |
exit(1) | |
o_alpha = ('-a', '') in opts | |
o_unicode = ('-u', '') in opts | |
o_unicode_compat = ('--unicode-compat', '') in opts | |
o_outfile = "" | |
for e in opts: | |
if e[0] == "-o": | |
o_outfile = e[1] | |
if o_unicode_compat and not o_unicode: | |
print("Warning: --unicode-compat without -u is no-op") | |
img = Image.open(args[0]) | |
if o_unicode: | |
warnlimit = 240 * 72 | |
else: | |
warnlimit = 120 * 36 | |
if img.size[0] * img.size[1] > warnlimit: | |
print("Warning: Big image, did you forget to scale it down?") | |
img = img.convert("RGBA" if o_alpha else "RGB") | |
imgd = img.load() | |
if o_outfile == "": | |
tf = StdoutWrapper() | |
else: | |
tf = open(o_outfile, "wb") | |
if not o_unicode: | |
for y in range(img.size[1]): | |
lastcc = -1 | |
for x in range(img.size[0]): | |
cc = -1 if o_alpha and imgd[x, y][3] < 128 else find_colorcode(imgd[x, y]) | |
if cc == lastcc: | |
tf.write(b" ") | |
else: | |
tf.write(ctrl_bg(cc) + b" ") # 2 spaces per pixel because chars are non-square | |
lastcc = cc | |
tf.write(b"\x1b[0m\n") | |
tf.flush() | |
else: | |
for y in range(0, img.size[1], 2): | |
lastfg, lastbg = -1, -1 | |
for x in range(img.size[0]): | |
if y == img.size[1] - 1: | |
ccbg = -1 | |
ccfg = -1 if o_alpha and imgd[x, y][3] < 128 else find_colorcode(imgd[x, y]) | |
else: | |
ccbg = -1 if o_alpha and imgd[x, y][3] < 128 else find_colorcode(imgd[x, y]) | |
ccfg = -1 if o_alpha and imgd[x, y+1][3] < 128 else find_colorcode(imgd[x, y+1]) | |
u = False | |
if ccfg == -1 and ccbg != -1 and not o_unicode_compat: | |
# This is needed to make transparency work when there are 2 pixels | |
# like this: | |
# [ NON-TRANSPARENT ] | |
# [ TRANSPARENT ] | |
# XXX: also causes ugly lines in xfce4-terminal | |
ccfg, ccbg = ccbg, ccfg | |
u = True | |
elif ccfg == lastbg and ccbg == lastfg and not o_unicode_compat: | |
# Optimize stuff by using UPPER HALF BLOCK and leaving colors alone | |
# instead of swapping colors and using default char | |
# XXX: Guess what? yep, causes glitches in xfce4-terminal | |
ccfg, ccbg = ccbg, ccfg | |
u = True | |
if ccfg != lastfg: | |
tf.write(ctrl_fg(ccfg)) | |
lastfg = ccfg | |
if ccbg != lastbg: | |
tf.write(ctrl_bg(ccbg)) | |
lastbg = ccbg | |
if ccfg == ccbg: | |
tf.write(b" ") | |
elif u: | |
tf.write("\u2580".encode('utf-8')) | |
elif y == img.size[1] - 1 and not o_unicode_compat: | |
# The last pixel row of an uneven image is encoded as UPPER HALF BLOCK | |
# with the default bg color and the pixel color as the fg color | |
# XXX: causes ugly lines in xfce4-terminal | |
tf.write("\u2580".encode('utf-8')) | |
else: | |
tf.write("\u2584".encode('utf-8')) | |
tf.write(b"\x1b[0m\n") | |
tf.flush() | |
tf.close() |
requirements for debian-like:
apt install python3-pip
pip3 install Pillow
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that you don't need this if you use the newer revision with the
-u
flag.