diff options
Diffstat (limited to 'pixelterm')
-rw-r--r-- | pixelterm/__init__.py | 1 | ||||
-rwxr-xr-x | pixelterm/colorcube.py | 25 | ||||
-rwxr-xr-x | pixelterm/gifterm.py | 89 | ||||
-rwxr-xr-x | pixelterm/pixelterm.py | 44 | ||||
-rwxr-xr-x | pixelterm/pngmeta.py | 16 | ||||
-rwxr-xr-x | pixelterm/resolvecolor.py | 17 | ||||
-rw-r--r-- | pixelterm/unpixelterm.py | 34 |
7 files changed, 5 insertions, 221 deletions
diff --git a/pixelterm/__init__.py b/pixelterm/__init__.py index 8692824..e69de29 100644 --- a/pixelterm/__init__.py +++ b/pixelterm/__init__.py @@ -1 +0,0 @@ -__all__ = ['xtermcolors', 'pixelterm'] diff --git a/pixelterm/colorcube.py b/pixelterm/colorcube.py deleted file mode 100755 index b7fe65c..0000000 --- a/pixelterm/colorcube.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python - -# Display an xterm-256color color palette on the terminal, including color ids - -reset_sequence = '\033[39;49m' - -def esc(i): - return '\033[48;5;'+str(i)+'m' - -def main(): - print(''.join([str(i).ljust(4) for i in range(16)])) - print(' '.join([esc(i) for i in range(16)])+' ' + reset_sequence) - - for j in range(6): - for k in range(6): - c = 16+j*6+k*6*6 - print(''.join([str(c+i).ljust(4) for i in range(6)])) - print(' '.join([esc(c+i) for i in range(6)])+' ' + reset_sequence) - - print(''.join([str(i).ljust(4) for i in range(16+6*6*6, 16+6*6*6+24)])) - print(' '.join([esc(i) for i in range(16+6*6*6, 16+6*6*6+24)])+' ' + reset_sequence) - -if __name__ == '__main__': - main() - diff --git a/pixelterm/gifterm.py b/pixelterm/gifterm.py deleted file mode 100755 index 4c87978..0000000 --- a/pixelterm/gifterm.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python - -import os, sys, argparse, os.path, json, time, signal, atexit -import pixelterm -from PIL import Image, GifImagePlugin, ImageSequence - -clear_screen = '\033[H\033[2J' -home_cursor = '\033[H' -cursor_invisible = '\033[?25l' -cursor_visible = '\033[?25h' - -def main(): - parser = argparse.ArgumentParser(description='Render pixel images on 256-color ANSI terminals') - parser.add_argument('image', type=str) - parser.add_argument('-s', '--size', type=str, help='Terminal size, [W]x[H]') - parser.add_argument('--serve', type=int, help='Serve via TCP on given port') - args = parser.parse_args() - - tw, th = None, None - if args.size: - tw, th = map(int, args.size.split('x')) - else: - try: - tw, th = os.get_terminal_size() - except: # If this is not a regular terminal - pass - th = th*2 - - img = Image.open(args.image) - palette = img.getpalette() - last_frame = Image.new("RGBA", img.size) - frames = [] - - for frame in ImageSequence.Iterator(img): - #This works around a known bug in Pillow - #See also: http://stackoverflow.com/questions/4904940/python-converting-gif-frames-to-png - frame.putpalette(palette) - c = frame.convert("RGBA") - - if img.info['background'] != img.info.get('transparency'): - last_frame.paste(c, c) - else: - last_frame = c - - im = last_frame.copy() - if (tw, th) != (None, None): - im.thumbnail((tw, th), Image.NEAREST) - frames.append(pixelterm.termify_pixels(im, True)) - - if args.serve: - from socketserver import ThreadingMixIn, TCPServer, BaseRequestHandler - - # Quote-Of-The-Day protocol implementation - # See RFC865 ( https://tools.ietf.org/html/rfc865 ) for details. - - class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass - - class QOTDHandler(BaseRequestHandler): - def handle(self): - try: - self.request.sendall(bytes(cursor_invisible, "UTF-8")) - while True: - for frame in frames: - self.request.sendall(bytes(home_cursor + pixelterm.reset_sequence, "UTF-8")) - self.request.sendall(bytes(frame, "UTF-8")) - time.sleep(min(1/10, img.info['duration']/1000.0)) - except: - pass - - server = ThreadingTCPServer(('', args.serve), QOTDHandler) - server.serve_forever() - else: - print(cursor_invisible) - atexit.register(lambda:print(cursor_visible)) - signal.signal(signal.SIGTERM, lambda signum, stack_frame: exit(1)) - - try: - while True: - for frame in frames: - print(home_cursor) - print(pixelterm.reset_sequence) - print(frame) - time.sleep(min(1/10, img.info['duration']/1000.0)) - except KeyboardInterrupt: - pass - -if __name__ == '__main__': - main() - diff --git a/pixelterm/pixelterm.py b/pixelterm/pixelterm.py index 74fe9f1..8a9d0be 100755 --- a/pixelterm/pixelterm.py +++ b/pixelterm/pixelterm.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import xtermcolors +from pixelterm.xtermcolors import closest_color reset_sequence = '\033[39;49m' @@ -20,7 +20,7 @@ def termify_pixels(img, fill=False): if color in bgd: return bgd[color] r,g,b,_ = color - bgd[color] = '\033[48;5;'+str(xtermcolors.closest_color(r,g,b))+'m' + bgd[color] = '\033[48;5;'+str(closest_color(r,g,b))+'m' return bgd[color] def fgescape(color): @@ -29,7 +29,7 @@ def termify_pixels(img, fill=False): return '' fg=color r,g,b,_ = color - fgd[color] = '\033[38;5;'+str(xtermcolors.closest_color(r,g,b))+'m' + fgd[color] = '\033[38;5;'+str(closest_color(r,g,b))+'m' return fgd[color] def balloon(x,y): @@ -69,41 +69,3 @@ def termify_pixels(img, fill=False): out = (out.rstrip() if bg == (0,0,0,0) and not fill else out) + '\n' return out[:-1] + reset_sequence + '\n' -def main(): - import os, sys, argparse, os.path, json - from multiprocessing.dummy import Pool - from PIL import Image, PngImagePlugin - - parser = argparse.ArgumentParser(description='Render pixel images on 256-color ANSI terminals') - parser.add_argument('image', type=str, nargs='*') - parser.add_argument('-d', '--output-dir', type=str, help='Output directory (if not given, output to stdout)') - args = parser.parse_args() - - def convert(f): - img = Image.open(f).convert("RGBA") - if args.output_dir: - print(f) - foo, _, _ = f.rpartition('.png') - output = os.path.join(args.output_dir, os.path.basename(foo)+'.pony') - metadata = json.loads(img.info.get('pixelterm-metadata')) - comment = metadata.get('_comment') - if comment is not None: - del metadata['_comment'] - comment = '\n'+comment - else: - comment = '' - metadataarea = '$$$\n' +\ - '\n'.join([ '\n'.join([ k.upper() + ': ' + v for v in metadata[k] ]) for k in sorted(metadata.keys()) ]) +\ - comment + '\n$$$\n' - with open(output, 'w') as of: - of.write(metadataarea) - of.write(termify_pixels(img)) - else: - print(termify_pixels(img)) - - p = Pool() - p.map(convert, args.image) - -if __name__ == '__main__': - main() - diff --git a/pixelterm/pngmeta.py b/pixelterm/pngmeta.py deleted file mode 100755 index 5ddde98..0000000 --- a/pixelterm/pngmeta.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python - -import os, sys, argparse -from PIL import Image, PngImagePlugin - -def main(): - parser = argparse.ArgumentParser(description='Print PNG metadata') - parser.add_argument('image', type=str) - args = parser.parse_args() - img = Image.open(args.image) - for k, v in img.info.items(): - print('{:15}: {}'.format(k, v)) - -if __name__ == '__main__': - main() - diff --git a/pixelterm/resolvecolor.py b/pixelterm/resolvecolor.py deleted file mode 100755 index 7fab111..0000000 --- a/pixelterm/resolvecolor.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -def main(): - import os, sys, argparse, os.path, json, re - from pixelterm import xtermcolors - - # Resolve HTML-style hex RGB color codes to xterm-256color color numbers - - if len(sys.argv) != 2: - print('Usage: resolvecolor.py #RRGGBB') - exit() - - print(xtermcolors.closest_color(*[int(s, 16) for s in re.match('#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})', sys.argv[1]).groups()])) - -if __name__ == '__main__': - main() - diff --git a/pixelterm/unpixelterm.py b/pixelterm/unpixelterm.py index 46c0c83..1159197 100644 --- a/pixelterm/unpixelterm.py +++ b/pixelterm/unpixelterm.py @@ -2,7 +2,7 @@ import os, sys, os.path from collections import defaultdict -from pixelterm import xtermcolors +from pixelterm.xtermcolors import xterm_colors from PIL import Image, PngImagePlugin try: import re2 as re @@ -16,7 +16,7 @@ def parse_escape_sequence(seq): while i<len(codes): if codes[i] in [38, 48]: if codes[i+1] == 5: - c = xtermcolors.xterm_colors[codes[i+2]] + c = xterm_colors[codes[i+2]] fg, bg = (c, bg) if codes[i] == 38 else (fg, c) i += 2 elif codes[i] == 39: @@ -90,33 +90,3 @@ def unpixelterm(text): x, y = 0, y+2 return img, metadata -def main(): - import argparse, json - - parser = argparse.ArgumentParser(description='Convert images rendered by pixelterm-like utilities back to PNG') - parser.add_argument('-v', '--verbose', action='store_true') - output_group = parser.add_mutually_exclusive_group() - output_group.add_argument('-o', '--output', type=str, help='Output file name, defaults to ${input%.pony}.png') - output_group.add_argument('-d', '--output-dir', type=str, help='Place output files here') - parser.add_argument('input', type=argparse.FileType('r'), nargs='+') - args = parser.parse_args() - if len(args.input) > 1 and args.output: - parser.print_help() - print('You probably do not want to overwrite the given output file {} times.'.format(len(args.input))) - sys.exit(1) - - for f in args.input: - if len(args.input) > 1: - print(f.name) - img, metadata = unpixelterm(f.read()) - pnginfo = PngImagePlugin.PngInfo() - pnginfo.add_text('pixelterm-metadata', json.dumps(metadata)) - foo, _, _ = f.name.rpartition('.pony') - output = args.output or foo+'.png' - if args.output_dir: - output = os.path.join(args.output_dir, os.path.basename(output)) - img.save(output, 'PNG', pnginfo=pnginfo) - -if __name__ == '__main__': - main() - |