diff options
-rwxr-xr-x | colorcube.py (renamed from colorcube) | 0 | ||||
-rwxr-xr-x | gifterm.py (renamed from gifterm) | 0 | ||||
-rwxr-xr-x | pixelterm | 36 | ||||
-rw-r--r-- | pixelterm.py | 47 | ||||
-rwxr-xr-x | pngmeta.py (renamed from pngmeta) | 0 | ||||
-rwxr-xr-x | resolvecolor | 15 | ||||
-rwxr-xr-x | resolvecolor.py | 13 | ||||
-rwxr-xr-x | setup.py | 17 | ||||
-rwxr-xr-x | unpixelterm | 38 | ||||
-rw-r--r-- | unpixelterm.py | 39 | ||||
-rw-r--r-- | xtermcolors.py | 21 |
11 files changed, 109 insertions, 117 deletions
diff --git a/pixelterm b/pixelterm deleted file mode 100755 index 79c9cd2..0000000 --- a/pixelterm +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -import os, sys, argparse, os.path, json -import pixelterm -from multiprocessing import Pool -from PIL import Image, PngImagePlugin - -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(pixelterm.termify_pixels(img)) - else: - print(pixelterm.termify_pixels(img)) - -if __name__ == '__main__': - 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() - p = Pool() - p.map(convert, args.image) diff --git a/pixelterm.py b/pixelterm.py index 1543663..8b4fabf 100644 --- a/pixelterm.py +++ b/pixelterm.py @@ -1,13 +1,8 @@ #!/usr/bin/env python -#NOTE: This script uses pygments for RGB->X256 conversion since pygments is -#readily available. If you do not like pygments (e.g. because it is large), -#you could patch in something like https://github.com/magarcia/python-x256 -#(but don't forget to send me a pull request ;) -from pygments.formatters import terminal256 +import xtermcolors -formatter = terminal256.Terminal256Formatter() -reset_sequence = terminal256.EscapeSequence(fg=formatter._closest_color(0,0,0), bg=formatter._closest_color(0,0,0)).reset_string() +reset_sequence = '\033[39;49m' def termify_pixels(img): sx, sy = img.size @@ -25,7 +20,7 @@ def termify_pixels(img): if color in bgd: return bgd[color] r,g,b,_ = color - bgd[color] = '\033[48;5;'+str(formatter._closest_color(r,g,b))+'m' + bgd[color] = '\033[48;5;'+str(xtermcolors.closest_color(r,g,b))+'m' return bgd[color] def fgescape(color): @@ -34,7 +29,7 @@ def termify_pixels(img): return '' fg=color r,g,b,_ = color - fgd[color] = '\033[38;5;'+str(formatter._closest_color(r,g,b))+'m' + fgd[color] = '\033[38;5;'+str(xtermcolors.closest_color(r,g,b))+'m' return fgd[color] def balloon(x,y): @@ -74,3 +69,37 @@ def termify_pixels(img): out = (out.rstrip() if bg == (0,0,0,0) else out) + '\n' return out[:-1] + reset_sequence + '\n' +if __name__ == '__main__': + import os, sys, argparse, os.path, json + from multiprocessing 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) diff --git a/resolvecolor b/resolvecolor deleted file mode 100755 index 7dc6537..0000000 --- a/resolvecolor +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -import os, sys, argparse, os.path, json, re -from pygments.formatters import terminal256 - -formatter = terminal256.Terminal256Formatter() - -# Resolve HTML-style hex RGB color codes to xterm-256color color numbers - -if len(sys.argv) != 2: - print('Usage: resolvecolor.py #RRGGBB') - exit() - -print(formatter._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()])) - diff --git a/resolvecolor.py b/resolvecolor.py new file mode 100755 index 0000000..988b5cd --- /dev/null +++ b/resolvecolor.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +import os, sys, argparse, os.path, json, re +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()])) + @@ -4,7 +4,7 @@ from setuptools import setup import os, os.path import sys -ver = "1.0" +ver = "1.1" def read(filename): return open(os.path.join(os.path.dirname(__file__), filename)).read() @@ -22,13 +22,14 @@ setup(name = 'pixelterm', author = 'jaseg', author_email = 'pixelterm@jaseg.net', url = 'https://github.com/jaseg/pixelterm', - py_modules = ['pixelterm', 'unpixelterm'], - scripts = ['pixelterm', - 'unpixelterm', - 'colorcube', - 'gifterm', - 'resolvecolor', - 'pngmeta'], + py_modules = ['pixelterm', 'unpixelterm', 'xtermcolors'], + install_requires=['pillow'], + scripts = ['pixelterm.py', + 'unpixelterm.py', + 'colorcube.py', + 'gifterm.py', + 'resolvecolor.py', + 'pngmeta.py'], zip_safe = True, classifiers = [ 'Development Status :: 5 - Production/Stable', diff --git a/unpixelterm b/unpixelterm deleted file mode 100755 index 4556d07..0000000 --- a/unpixelterm +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python - -import os, sys, argparse, os.path, json, unpixelterm -#NOTE: This script uses pygments for X256->RGB conversion since pygments is -#readily available. If you do not like pygments (e.g. because it is large), -#you could patch in something like https://github.com/magarcia/python-x256 -#(but don't forget to send me a pull request ;) -from pygments.formatters import terminal256 -from PIL import Image, PngImagePlugin -try: - import re2 as re -except: - import re - -if __name__ == '__main__': - 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.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) diff --git a/unpixelterm.py b/unpixelterm.py index 234d3d1..d9b1498 100644 --- a/unpixelterm.py +++ b/unpixelterm.py @@ -2,22 +2,13 @@ import os, sys, os.path from collections import defaultdict -#NOTE: This script uses pygments for X256->RGB conversion since pygments is -#readily available. If you do not like pygments (e.g. because it is large), -#you could patch in something like https://github.com/magarcia/python-x256 -#(but don't forget to send me a pull request ;) -from pygments.formatters import terminal256 +import xtermcolors from PIL import Image, PngImagePlugin try: import re2 as re except: import re -formatter = terminal256.Terminal256Formatter() -#HACK this adds two missing entries to pygment's color table -formatter.xterm_colors.append((0xe4, 0xe4, 0xe4)) -formatter.xterm_colors.append((0xee, 0xee, 0xee)) - def parse_escape_sequence(seq): codes = list(map(int, seq[2:-1].split(';'))) fg, bg = None, None @@ -25,7 +16,7 @@ def parse_escape_sequence(seq): while i<len(codes): if codes[i] in [38, 48]: if codes[i+1] == 5: - c = formatter.xterm_colors[codes[i+2]] + c = xtermcolors.xterm_colors[codes[i+2]] fg, bg = (c, bg) if codes[i] == 38 else (fg, c) i += 2 elif codes[i] == 39: @@ -99,3 +90,29 @@ def unpixelterm(text): x, y = 0, y+2 return img, metadata +if __name__ == '__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) diff --git a/xtermcolors.py b/xtermcolors.py new file mode 100644 index 0000000..36cddc6 --- /dev/null +++ b/xtermcolors.py @@ -0,0 +1,21 @@ + +xterm_colors = [] + +# This is ripped out of pygments +# I leave out the 16 standard colors since people tend to re-define them to their liking. + +# colors 16..232: the 6x6x6 color cube +_valuerange = (0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff) +for i in range(217): + r = _valuerange[(i // 36) % 6] + g = _valuerange[(i // 6) % 6] + b = _valuerange[i % 6] + xterm_colors.append((r, g, b)) + +# colors 233..253: grayscale +for i in range(1, 24): + v = 8 + i * 10 + xterm_colors.append((v, v, v)) + +def closest_color(r, g, b): + return 16+min([ ((r-rt)**2+(g-gt)**2+(b-bt)**2, i) for i,(rt,gt,bt) in enumerate(xterm_colors) ])[1] |