mirror of
https://github.com/waveplate/img2irc.git
synced 2025-06-07 18:59:53 +00:00
64 lines
2.6 KiB
Python
64 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
||
import argparse
|
||
import json
|
||
from PIL import Image
|
||
|
||
def main():
|
||
p = argparse.ArgumentParser(
|
||
description="Slice a row-image of glyphs into bitmaps and output JSON mapping."
|
||
)
|
||
p.add_argument('chars_file', help='Space-delimited glyphs text file (UTF-8)')
|
||
p.add_argument('image_file', help='Image with glyphs in one row, no gaps')
|
||
p.add_argument('--icw', type=int, required=True, help='Input char width (px)')
|
||
p.add_argument('--ich', type=int, required=True, help='Input char height (px)')
|
||
p.add_argument('--threshold', type=int, required=True, help='B/W threshold (0–255)')
|
||
p.add_argument('--obw', type=int, required=True, help='Output bitmap width')
|
||
p.add_argument('--obh', type=int, required=True, help='Output bitmap height')
|
||
p.add_argument('--output', required=True, help='Output JSON filename')
|
||
args = p.parse_args()
|
||
|
||
# 1) Read glyphs
|
||
with open(args.chars_file, 'r', encoding='utf-8') as f:
|
||
glyphs = f.read().strip().split(' ')
|
||
|
||
# 2) Load image & sanity-check
|
||
im = Image.open(args.image_file).convert('L')
|
||
w, h = im.size
|
||
if h != args.ich:
|
||
raise ValueError(f"Image height {h} ≠ ich {args.ich}")
|
||
count = w // args.icw
|
||
if count * args.icw != w:
|
||
raise ValueError(f"Image width {w} not a multiple of icw {args.icw}")
|
||
if len(glyphs) != count:
|
||
raise ValueError(f"{len(glyphs)} glyphs but {count} blocks in image")
|
||
|
||
# 3) Build mapping glyph → grid
|
||
mapping = {}
|
||
for i, glyph in enumerate(glyphs):
|
||
left = i * args.icw
|
||
block = im.crop((left, 0, left + args.icw, args.ich))
|
||
block = block.resize((args.obw, args.obh), Image.LANCZOS)
|
||
data = list(block.getdata())
|
||
bits = [1 if pix > args.threshold else 0 for pix in data]
|
||
grid = [bits[row*args.obw:(row+1)*args.obw] for row in range(args.obh)]
|
||
mapping[glyph] = grid
|
||
|
||
# 4) Write JSON manually so rows stay inline
|
||
with open(args.output, 'w', encoding='utf-8') as out:
|
||
out.write('{\n')
|
||
total = len(mapping)
|
||
for idx, (glyph, grid) in enumerate(mapping.items()):
|
||
# properly quote the glyph
|
||
key = json.dumps(glyph, ensure_ascii=False)
|
||
out.write(f' {key}: [\n')
|
||
for ridx, row in enumerate(grid):
|
||
row_str = ','.join(str(bit) for bit in row)
|
||
comma = ',' if ridx < len(grid) - 1 else ''
|
||
out.write(f' [{row_str}]{comma}\n')
|
||
out.write(' ]')
|
||
out.write(',\n' if idx < total - 1 else '\n')
|
||
out.write('}\n')
|
||
|
||
if __name__ == '__main__':
|
||
main()
|