Added a basic unpixelterm script. Misses metadata support.
This commit is contained in:
parent
938d6298e2
commit
76bc6482a6
1 changed files with 81 additions and 0 deletions
81
unpixelterm.py
Executable file
81
unpixelterm.py
Executable file
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os, sys, argparse
|
||||
#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
|
||||
|
||||
formatter = terminal256.Terminal256Formatter()
|
||||
|
||||
def parse_escape_sequence(seq):
|
||||
codes = list(map(int, seq.lstrip('\x1b[').rstrip('m').split(';')))
|
||||
fg, bg = None, None
|
||||
i = 0
|
||||
while i<len(codes):
|
||||
if codes[i] in [38, 48]:
|
||||
if codes[i+1] == 5:
|
||||
c = formatter.xterm_colors[codes[i+2]]
|
||||
fg, bg = (c, bg) if codes[i] == 38 else (fg, c)
|
||||
i += 2
|
||||
elif codes[i] == 39:
|
||||
fg = (0,0,0,0)
|
||||
elif codes[i] == 49:
|
||||
bg = (0,0,0,0)
|
||||
i += 1
|
||||
return fg, bg
|
||||
|
||||
def unpixelterm(text):
|
||||
lines = text.split('\n')
|
||||
h = len(lines)*2
|
||||
w = max([ len(re.sub(r'\x1b\[[0-9;]+m|\$.*\$', '', line)) for line in lines ])
|
||||
img = Image.new('RGBA', (w, h))
|
||||
fg, bg = (0,0,0,0), (0,0,0,0)
|
||||
x, y = 0, 0
|
||||
for escapeseq, specialstr, char, newline in re.findall(r'(\x1b\[[0-9;]+m)|(\$.*\$)|(.)|(\n)', text):
|
||||
if escapeseq:
|
||||
nfg, nbg = parse_escape_sequence(escapeseq)
|
||||
fg, bg = nfg or fg, nbg or bg
|
||||
elif specialstr:
|
||||
if specialstr.startswith('$$$'): #metadata
|
||||
pass
|
||||
elif specialstr == '$\\$':
|
||||
img.putpixel((x, y), (255, 0, 0, 127))
|
||||
img.putpixel((x, y+1), (255, 0, 0, 127))
|
||||
x += 1
|
||||
elif specialstr == '$/$':
|
||||
img.putpixel((x, y), (0, 0, 255, 127))
|
||||
img.putpixel((x, y+1), (0, 0, 255, 127))
|
||||
x += 1
|
||||
else: #(should be a) balloon
|
||||
bw = int(re.match(r'\$balloon([0-9]*)\$', specialstr).group(1))
|
||||
for i in range(x, x+bw):
|
||||
img.putpixel((i, y), (0, 255, 0, 127))
|
||||
img.putpixel((i, y+1), (0, 255, 0, 127))
|
||||
x += bw
|
||||
elif char:
|
||||
#Da magicks: ▀█▄
|
||||
c = {' ': (bg, bg),
|
||||
'█': (fg, fg),
|
||||
'▀': (fg, bg),
|
||||
'▄': (bg, fg)}[char]
|
||||
img.putpixel((x, y), c[0])
|
||||
img.putpixel((x, y+1), c[1])
|
||||
x += 1
|
||||
else: #newline
|
||||
x, y = 0, y+2
|
||||
return img
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Convert images rendered by pixelterm-like utilities back to PNG')
|
||||
parser.add_argument('input', type=argparse.FileType('r'))
|
||||
parser.add_argument('output', type=str)
|
||||
args = parser.parse_args()
|
||||
img = unpixelterm(args.input.read())
|
||||
img.save(args.output)
|
||||
Loading…
Add table
Add a link
Reference in a new issue