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 \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()