Files
gnwmanager/scripts/img2pixel.py
2023-08-19 15:52:11 -07:00

102 lines
2.8 KiB
Python

import argparse
import sys
from pathlib import Path
from PIL import Image
def write_pixels(prefix, fn, invert=False):
img = Image.open(fn).convert(mode="RGB")
out = [
f"const glyph_t {prefix}{fn.stem} = {{\n",
f" .height = {img.height},\n",
f" .width = {img.width},\n",
" .data = {\n",
]
header = f"extern const glyph_t {prefix}{fn.stem};\n"
for y in range(img.height):
bits_data = 0
bits_count = 0
hex_data = [" "]
comment_graphic = [
" // ",
]
for x in range(img.width):
pixel = img.getpixel((x, y))
pixel = sum(pixel) / len(pixel)
if invert:
if pixel < 127:
bits_data |= 1 << (7 - bits_count)
comment_graphic.append("#")
else:
comment_graphic.append(" ")
else:
if pixel > 127:
bits_data |= 1 << (7 - bits_count)
comment_graphic.append("#")
else:
comment_graphic.append(" ")
bits_count += 1
if bits_count == 8:
hex_data.append(f"0x{bits_data:02X}, ")
bits_data, bits_count = 0, 0
if bits_count:
hex_data.append(f"0x{bits_data:02X}, ")
bits_data, bits_count = 0, 0
out.extend(hex_data)
out.append("".join(comment_graphic).rstrip())
out.append("\n")
out.append(" }\n")
out.append("};\n")
return "".join(out), header
def main():
parser = argparse.ArgumentParser()
parser.add_argument("dir", type=Path)
parser.add_argument("--output-c", type=Path, default="Core/Src/segments.c")
parser.add_argument("--output-h", type=Path, default="Core/Inc/segments.h")
parser.add_argument("--prefix", default="img_")
parser.add_argument("--invert", action="store_true")
args = parser.parse_args()
output_cs = [
"// Do not directly modify.\n",
f"// Generated by {' '.join(sys.argv)}\n",
'#include "segments.h"\n',
"\n",
]
output_hs = [
"#pragma once\n// Do not directly modify.\n",
f"// Generated by {' '.join(sys.argv)}\n",
"\n",
"#include <stdint.h>\n",
"\n",
"typedef struct {\n",
" uint16_t width;\n",
" uint16_t height;\n",
" const char data[];\n",
"} glyph_t;\n",
"\n",
]
for fn in sorted(args.dir.glob("*.png")):
output_cs.append("\n")
c, h = write_pixels(args.prefix, fn, invert=args.invert)
output_cs.append(c)
output_hs.append(h)
args.output_c.write_text("".join(output_cs))
args.output_h.write_text("".join(output_hs))
if __name__ == "__main__":
main()