Files
q-tools/files/chr2pix
2024-12-11 14:23:31 +02:00

118 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
from argparse import ArgumentParser
import numpy as n
from PIL import Image
UNIMAP = {
" ": [0, 0, 0, 0],
"": [255, 255, 255, 255],
"": [0, 0, 255, 255],
"": [255, 255, 0, 0],
"": [255, 0, 255, 0],
"": [0, 255, 0, 255],
"": [0, 0, 255, 0],
"": [0, 0, 0, 255],
"": [255, 0, 0, 0],
"": [0, 255, 0, 0],
"": [255, 0, 0, 255],
"": [0, 255, 255, 0],
"": [255, 0, 255, 255],
"": [255, 255, 255, 0],
"": [255, 255, 0, 255],
"": [0, 255, 255, 255],
}
for key in UNIMAP:
UNIMAP[key] = n.array(UNIMAP[key])
def get_ascii(c):
if c > 127:
return "X"
if c == 0:
return " "
return "."
def get_unicode(c):
minerr = 8192
minchar = " "
for key in UNIMAP:
err = n.sum(n.abs(UNIMAP[key] - 4*n.clip(c,0,63)))
if err < minerr:
minerr = err
minchar = key
return minchar
def png2uni(inFile):
im = Image.open(inFile).convert("L")
# ~ im = im.resize((im.size[0], int(im.size[1]/2)), Image.BICUBIC)
# ~ im = im.resize((2 * im.size[0], int(im.size[1])), Image.NEAREST)
pixels = im.load()
chars = [["." for c in range(0, int(im.size[0] / 2))] for r in range(0, int(im.size[1] / 2))]
for r in range(0, im.size[1], 2):
for c in range(0, im.size[0], 2):
try:
char = get_unicode(
n.array([pixels[c + 0, r + 0], pixels[c + 1, r + 0], pixels[c + 0, r + 1], pixels[c + 1, r + 1]])
)
c_r = int(r / 2)
c_c = int(c / 2)
chars[c_r][c_c] = char
except IndexError:
pass
for row in chars:
print("".join(row))
def png2asc(inFile):
im = Image.open(inFile).convert("L")
pixels = im.load()
for r in range(im.size[1]):
for c in range(im.size[0]):
char = get_ascii(pixels[c, r])
sys.stdout.write(char)
sys.stdout.write("\n")
def asc2png(inFile, outFile):
reader = open(inFile, "r")
coords = []
max_c = 0
for r, row in enumerate(reader):
for c, col in enumerate(row):
if col not in (" ", "\n"):
if col == ".":
coords.append((r, c, 127))
else:
coords.append((r, c, 255))
max_c = max(max_c, c)
im = n.zeros((r + 1, max_c), dtype=n.uint8)
for c in coords:
im[c[0], c[1]] = c[2]
data = Image.fromarray(im)
data.save(outFile)
if __name__ == "__main__":
parser = ArgumentParser(
description="Convert image to ascii, or ascii to image. If only input is defined, it is assumed as image (PNG)."
)
parser.add_argument("--unicode", "-u", default=False, action="store_true", help="Unicode characters")
parser.add_argument("input", action="store")
parser.add_argument("output", action="store", nargs="?")
opts = parser.parse_args()
if opts.output == None:
if opts.unicode:
png2uni(opts.input)
else:
png2asc(opts.input)
else:
asc2png(opts.input, opts.output)