aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rwxr-xr-xcolorcube (renamed from colorcube.py)0
-rwxr-xr-xgifterm55
-rwxr-xr-xgifterm.py123
-rwxr-xr-xpixelterm28
-rwxr-xr-xpixelterm.py25
-rwxr-xr-xpngmeta (renamed from pngmeta.py)0
-rwxr-xr-xresolvecolor (renamed from resolvecolor.py)0
-rwxr-xr-xsetup.py50
-rwxr-xr-xunpixelterm38
-rwxr-xr-xunpixelterm.py26
11 files changed, 176 insertions, 173 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3d7bfbb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+build
+dist
+pixelterm.egg-info
+__pycache__
diff --git a/colorcube.py b/colorcube
index ebf36b9..ebf36b9 100755
--- a/colorcube.py
+++ b/colorcube
diff --git a/gifterm b/gifterm
new file mode 100755
index 0000000..99cbb5f
--- /dev/null
+++ b/gifterm
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+import os, sys, argparse, os.path, json, time, signal, atexit, pixelterm
+#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
+from PIL import Image, GifImagePlugin, ImageSequence
+
+clear_screen = '\033[H\033[2J'
+cursor_invisible = '\033[?25l'
+cursor_visible = '\033[?25h'
+
+if __name__ == '__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]')
+ args = parser.parse_args()
+
+ tw, th = os.get_terminal_size()
+ th = th*2
+ if args.size:
+ tw, th = map(int, args.size.split('x'))
+
+ 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['transparency']:
+ last_frame.paste(c, c)
+ else:
+ last_frame = c
+
+ im = last_frame.copy()
+ im.thumbnail((tw, th), Image.NEAREST)
+ frames.append(pixelterm.termify_pixels(im))
+
+ print(cursor_invisible)
+ atexit.register(lambda:print(cursor_visible))
+ signal.signal(signal.SIGTERM, lambda signum, stack_frame: exit(1))
+
+ while True:
+ for frame in frames:
+ print(clear_screen, pixelterm.reset_sequence)
+ print(frame)
+ time.sleep(img.info['duration']/1000.0)
+
diff --git a/gifterm.py b/gifterm.py
deleted file mode 100755
index cef85b9..0000000
--- a/gifterm.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python
-
-import os, sys, argparse, os.path, json, time, signal, atexit
-#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
-from PIL import Image, GifImagePlugin, ImageSequence
-
-clear_screen = '\033[H\033[2J'
-cursor_invisible = '\033[?25l'
-cursor_visible = '\033[?25h'
-
-formatter = terminal256.Terminal256Formatter()
-reset_sequence = terminal256.EscapeSequence(fg=formatter._closest_color(0,0,0), bg=formatter._closest_color(0,0,0)).reset_string()
-
-def termify_pixels(img):
- sx, sy = img.size
- out = ''
-
- fg,bg = None,None
- fgd,bgd = {},{}
- def bgescape(color):
- nonlocal bg, bgd
- if bg == color:
- return ''
- bg=color
- if color == (0,0,0,0):
- return '\033[49m'
- if color in bgd:
- return bgd[color]
- r,g,b,_ = color
- bgd[color] = '\033[48;5;'+str(formatter._closest_color(r,g,b))+'m'
- return bgd[color]
-
- def fgescape(color):
- nonlocal fg, fgd
- if fg == color:
- return ''
- fg=color
- r,g,b,_ = color
- fgd[color] = '\033[38;5;'+str(formatter._closest_color(r,g,b))+'m'
- return fgd[color]
-
- def balloon(x,y):
- if x+1 == img.size[0] or img.im.getpixel((x+1, y)) != (0,255,0,127):
- w = 1
- while x-w >= 0 and img.im.getpixel((x-w, y)) == (0,255,0,127):
- w += 1
- return '$balloon{}$'.format(w)
- return ''
-
- for y in range(0, sy, 2):
- for x in range(sx):
- coltop = img.im.getpixel((x, y))
- colbot = img.im.getpixel((x, y+1)) if y+1 < img.size[1] else (0,0,0,0)
-
- if coltop[3] == 127: #Control colors
- out += reset_sequence
- out += {(255, 0, 0, 127): lambda x,y:'$\\$',
- (0, 0, 255, 127): lambda x,y:'$/$',
- (0, 255, 0, 127): balloon
- }.get(coltop, lambda x,y:' ')(x,y)
- continue
-
- if coltop[3] != 255:
- coltop = (0,0,0,0)
- if colbot[3] != 255:
- colbot = (0,0,0,0)
-
- #Da magicks: ▀█▄
- c,cf = '▀','█'
- te,be = fgescape,bgescape
- if coltop == (0,0,0,0) or ((coltop == bg or colbot == fg) and not colbot == (0,0,0,0)):
- c,cf,te,be = '▄',' ',be,te
- if colbot == coltop:
- c,te,be = cf,te,te
- out += te(coltop) + be(colbot) + c
- out = (out.rstrip() if bg == (0,0,0,0) else out) + '\n'
- return out[:-1] + reset_sequence + '\n'
-
-if __name__ == '__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]')
- args = parser.parse_args()
-
- tw, th = os.get_terminal_size()
- th = th*2
- if args.size:
- tw, th = map(int, args.size.split('x'))
-
- 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['transparency']:
- last_frame.paste(c, c)
- else:
- last_frame = c
-
- im = last_frame.copy()
- im.thumbnail((tw, th), Image.NEAREST)
- frames.append(termify_pixels(im))
-
- print(cursor_invisible)
- atexit.register(lambda:print(cursor_visible))
- signal.signal(signal.SIGTERM, lambda signum, stack_frame: exit(1))
-
- while True:
- for frame in frames:
- print(clear_screen, reset_sequence)
- print(frame)
- time.sleep(img.info['duration']/1000.0)
-
diff --git a/pixelterm b/pixelterm
new file mode 100755
index 0000000..f893875
--- /dev/null
+++ b/pixelterm
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+import os, sys, argparse, os.path, json, pixelterm
+from PIL import Image, PngImagePlugin
+
+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()
+ for f in args.image:
+ 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['_comment']
+ del metadata['_comment']
+ metadataarea = '$$$\n' +\
+ '\n'.join([ '\n'.join([ k.upper() + ': ' + v for v in metadata[k] ]) for k in sorted(metadata.keys()) ]) +\
+ '\n' + comment +\
+ '\n$$$\n'
+ with open(output, 'w') as of:
+ of.write(metadataarea)
+ of.write(pixelterm.termify_pixels(img))
+ else:
+ print(pixelterm.termify_pixels(img))
diff --git a/pixelterm.py b/pixelterm.py
index ab4409c..1543663 100755
--- a/pixelterm.py
+++ b/pixelterm.py
@@ -1,12 +1,10 @@
#!/usr/bin/env python
-import os, sys, argparse, os.path, json
#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
-from PIL import Image, PngImagePlugin
formatter = terminal256.Terminal256Formatter()
reset_sequence = terminal256.EscapeSequence(fg=formatter._closest_color(0,0,0), bg=formatter._closest_color(0,0,0)).reset_string()
@@ -76,26 +74,3 @@ 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__':
- 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()
- for f in args.image:
- 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['_comment']
- del metadata['_comment']
- metadataarea = '$$$\n' +\
- '\n'.join([ '\n'.join([ k.upper() + ': ' + v for v in metadata[k] ]) for k in sorted(metadata.keys()) ]) +\
- '\n' + comment +\
- '\n$$$\n'
- with open(output, 'w') as of:
- of.write(metadataarea)
- of.write(termify_pixels(img))
- else:
- print(termify_pixels(img))
diff --git a/pngmeta.py b/pngmeta
index e6d9b6b..e6d9b6b 100755
--- a/pngmeta.py
+++ b/pngmeta
diff --git a/resolvecolor.py b/resolvecolor
index 7dc6537..7dc6537 100755
--- a/resolvecolor.py
+++ b/resolvecolor
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..983d45a
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+from setuptools import setup
+
+import os, os.path
+import sys
+
+ver = "1.0"
+
+def read(filename):
+ return open(os.path.join(os.path.dirname(__file__), filename)).read()
+
+
+
+if sys.version_info < (3,0):
+ print('Oops, only python >= 3.0 supported!')
+ sys.exit()
+
+setup(name = 'pixelterm',
+ version = ver,
+ description = 'Render pixely images on your terminal. Now also with animated GIF support.',
+ license = 'BSD',
+ author = 'jaseg',
+ author_email = 'pixelterm@jaseg.net',
+ url = 'https://github.com/jaseg/pixelterm',
+ py_modules = ['pixelterm', 'unpixelterm'],
+ scripts = ['pixelterm',
+ 'unpixelterm',
+ 'colorcube',
+ 'gifterm',
+ 'resolvecolor',
+ 'pngmeta'],
+ zip_safe = True,
+ classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Console',
+ 'Intended Audience :: Information Technology',
+ 'Intended Audience :: Intended Audience :: End Users/Desktop',
+ 'License :: Freely Distributable',
+ 'License :: OSI Approved :: BSD License',
+ 'Programming Language :: Python :: 3',
+ 'Topic :: Internet',
+ 'Topic :: Graphics',
+ 'Topic :: System :: Networking'
+ 'Topic :: Text Processing :: Filters',
+ 'Topic :: Utilities',
+ ],
+
+ long_description = read('README.md'),
+ dependency_links = [],
+)
diff --git a/unpixelterm b/unpixelterm
new file mode 100755
index 0000000..4556d07
--- /dev/null
+++ b/unpixelterm
@@ -0,0 +1,38 @@
+#!/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 416a057..234d3d1 100755
--- a/unpixelterm.py
+++ b/unpixelterm.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-import os, sys, argparse, os.path, json
+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),
@@ -99,27 +99,3 @@ def unpixelterm(text):
x, y = 0, y+2
return img, metadata
-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(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)