From e68a10fbae8a2cbbf2bce6321432b24eb12bd215 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sat, 6 Apr 2013 16:07:29 +0200 Subject: Added metadata handling and a PNG metadata extraction tool --- pngmeta.py | 11 ++++++++ unpixelterm.py | 85 +++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 62 insertions(+), 34 deletions(-) create mode 100755 pngmeta.py diff --git a/pngmeta.py b/pngmeta.py new file mode 100755 index 0000000..e6d9b6b --- /dev/null +++ b/pngmeta.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os, sys, argparse +from PIL import Image, PngImagePlugin + +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)) diff --git a/unpixelterm.py b/unpixelterm.py index b5a9bf4..4091dfb 100755 --- a/unpixelterm.py +++ b/unpixelterm.py @@ -33,49 +33,66 @@ def parse_escape_sequence(seq): def unpixelterm(text): lines = text.split('\n') + metadata = {} + try: + first = lines.index('$$$') + second = lines[first+1:].index('$$$') + foo = [ line.split(': ') for line in lines[first+1:second] if line != '' ] + d = {} + for k,v in foo: + if k not in ['WIDTH', 'HEIGHT']: + d[k.lower()] = d.get(k.lower(), []) + [v] + metadata.update(d) + lines[first:] = lines[first+1+second+1:] + except: + pass + 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)) + for line in lines: + for escapeseq, specialstr, char in re.findall(r'(\x1b\[[0-9;]+m)|(\$[^$]+\$)|(.)', line, re.DOTALL): + if escapeseq: + nfg, nbg = parse_escape_sequence(escapeseq) + fg, bg = nfg or fg, nbg or bg + elif specialstr: + if 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: #(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 + 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('input', type=argparse.FileType('r')) parser.add_argument('output', type=str) args = parser.parse_args() - img = unpixelterm(args.input.read()) - img.save(args.output) + img, metadata = unpixelterm(args.input.read()) + print('Metadata:') + pnginfo = PngImagePlugin.PngInfo() + for k, v in metadata.items(): + print('{:15}: {}'.format(k, '/'.join(v))) + pnginfo.add_text(k, '/'.join(v)) + img.save(args.output, 'PNG', pnginfo=pnginfo) -- cgit