#!/usr/bin/env python3 import numpy as np def load(image_path): from PIL import Image image = np.array(Image.open(image_path).convert("RGB")) height, width, channels = image.shape charwidth = 0 separator = (255, 0, 255) # magenta, a la LÖVE previous = -1 glyphs = [] for x, c in enumerate(image[0]): if np.all(c == separator): if not charwidth and previous < 0: previous = x continue if not charwidth: charwidth = x - previous assert charwidth == x - previous, "font must be monospace" glyph = image[:, previous + 1 : x] glyphs.append(glyph) previous = x return np.any(glyphs, axis=-1).astype(np.uint8) charset = "\ \x00☺☻♥♦♣♠•◘○◙♂♀♪♫☼\ ►◄↕‼¶§▬↨↑↓→←∟↔▲▼\ !\"#$%&'()*+,-./\ 0123456789:;<=>?\ @ABCDEFGHIJKLMNO\ PQRSTUVWXYZ[\\]^_\ `abcdefghijklmno\ pqrstuvwxyz{|}~⌂\ ÇüéâäàåçêëèïîìÄÅ\ ÉæÆôöòûùÿÖÜ¢£¥₧ƒ\ áíóúñѪº¿⌐¬½¼¡«»\ ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐\ └┴┬├─┼╞╟╚╔╩╦╠═╬╧\ ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀\ αßΓπΣσµτΦΘΩδ∞φε∩\ ≡±≥≤⌠⌡÷≈°∙·√ⁿ²■�" assert len(charset) == 256 chars = b"\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x7E\xC3\x81\xA5\x81\xBD\x99\xC3\x7E\x00\x00\ \x00\x7E\xFF\xFF\xDB\xFF\xC3\xE7\xFF\x7E\x00\x00\ \x00\x00\x44\xEE\xFE\xFE\xFE\x7C\x38\x10\x00\x00\ \x00\x10\x38\x7C\xFE\xFE\x7C\x38\x10\x00\x00\x00\ \x00\x18\x3C\x3C\xFF\xE7\xE7\x18\x18\x7E\x00\x00\ \x00\x18\x3C\x7E\xFF\xFF\x7E\x18\x18\x7E\x00\x00\ \x00\x00\x00\x00\x3C\x7E\x7E\x3C\x00\x00\x00\x00\ \xFF\xFF\xFF\xFF\xC3\x81\x81\xC3\xFF\xFF\xFF\xFF\ \x00\x00\x3C\x7E\x66\x42\x42\x66\x7E\x3C\x00\x00\ \xFF\xFF\xC3\x81\x99\xBD\xBD\x99\x81\xC3\xFF\xFF\ \x00\x3E\x0E\x3A\x72\xF8\xCC\xCC\xCC\x78\x00\x00\ \x00\x3C\x66\x66\x66\x3C\x18\x7E\x18\x18\x00\x00\ \x00\x1F\x19\x19\x1F\x18\x18\x78\xF8\x70\x00\x00\ \x00\x7F\x63\x7F\x63\x63\x63\x67\xE7\xE6\xC0\x00\ \x00\x00\x18\xDB\x7E\xE7\xE7\x7E\xDB\x18\x00\x00\ \x00\x80\xC0\xE0\xF8\xFE\xF8\xE0\xC0\x80\x00\x00\ \x00\x02\x06\x0E\x3E\xFE\x3E\x0E\x06\x02\x00\x00\ \x00\x18\x3C\x7E\x18\x18\x18\x7E\x3C\x18\x00\x00\ \x00\x66\x66\x66\x66\x66\x00\x00\x66\x66\x00\x00\ \x00\x7F\xDB\xDB\xDB\x7B\x1B\x1B\x1B\x1B\x00\x00\ \x00\x7E\x63\x30\x3C\x66\x66\x3C\x0C\xC6\x7E\x00\ \x00\x00\x00\x00\x00\x00\x00\xFE\xFE\xFE\x00\x00\ \x00\x18\x3C\x7E\x18\x18\x18\x7E\x3C\x18\x7E\x00\ \x00\x18\x3C\x7E\x18\x18\x18\x18\x18\x18\x00\x00\ \x00\x18\x18\x18\x18\x18\x18\x7E\x3C\x18\x00\x00\ \x00\x00\x00\x18\x0C\xFE\x0C\x18\x00\x00\x00\x00\ \x00\x00\x00\x30\x60\xFE\x60\x30\x00\x00\x00\x00\ \x00\x00\x00\x00\xC0\xC0\xC0\xFE\x00\x00\x00\x00\ \x00\x00\x00\x24\x66\xFF\x66\x24\x00\x00\x00\x00\ \x00\x00\x10\x10\x38\x38\x7C\x7C\xFE\xFE\x00\x00\ \x00\x00\xFE\xFE\x7C\x7C\x38\x38\x10\x10\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x30\x78\x78\x78\x30\x30\x00\x30\x30\x00\x00\ \x00\x66\x66\x66\x24\x00\x00\x00\x00\x00\x00\x00\ \x00\x6C\x6C\xFE\x6C\x6C\x6C\xFE\x6C\x6C\x00\x00\ \x30\x30\x7C\xC0\xC0\x78\x0C\x0C\xF8\x30\x30\x00\ \x00\x00\x00\xC4\xCC\x18\x30\x60\xCC\x8C\x00\x00\ \x00\x70\xD8\xD8\x70\xFA\xDE\xCC\xDC\x76\x00\x00\ \x00\x30\x30\x30\x60\x00\x00\x00\x00\x00\x00\x00\ \x00\x0C\x18\x30\x60\x60\x60\x30\x18\x0C\x00\x00\ \x00\x60\x30\x18\x0C\x0C\x0C\x18\x30\x60\x00\x00\ \x00\x00\x00\x66\x3C\xFF\x3C\x66\x00\x00\x00\x00\ \x00\x00\x00\x18\x18\x7E\x18\x18\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x38\x38\x60\x00\ \x00\x00\x00\x00\x00\xFE\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x38\x38\x00\x00\ \x00\x00\x02\x06\x0C\x18\x30\x60\xC0\x80\x00\x00\ \x00\x7C\xC6\xCE\xDE\xD6\xF6\xE6\xC6\x7C\x00\x00\ \x00\x10\x30\xF0\x30\x30\x30\x30\x30\xFC\x00\x00\ \x00\x78\xCC\xCC\x0C\x18\x30\x60\xCC\xFC\x00\x00\ \x00\x78\xCC\x0C\x0C\x38\x0C\x0C\xCC\x78\x00\x00\ \x00\x0C\x1C\x3C\x6C\xCC\xFE\x0C\x0C\x1E\x00\x00\ \x00\xFC\xC0\xC0\xC0\xF8\x0C\x0C\xCC\x78\x00\x00\ \x00\x38\x60\xC0\xC0\xF8\xCC\xCC\xCC\x78\x00\x00\ \x00\xFE\xC6\xC6\x06\x0C\x18\x30\x30\x30\x00\x00\ \x00\x78\xCC\xCC\xEC\x78\xDC\xCC\xCC\x78\x00\x00\ \x00\x78\xCC\xCC\xCC\x7C\x18\x18\x30\x70\x00\x00\ \x00\x00\x00\x38\x38\x00\x00\x38\x38\x00\x00\x00\ \x00\x00\x00\x38\x38\x00\x00\x38\x38\x18\x30\x00\ \x00\x0C\x18\x30\x60\xC0\x60\x30\x18\x0C\x00\x00\ \x00\x00\x00\x00\x7E\x00\x7E\x00\x00\x00\x00\x00\ \x00\x60\x30\x18\x0C\x06\x0C\x18\x30\x60\x00\x00\ \x00\x78\xCC\x0C\x18\x30\x30\x00\x30\x30\x00\x00\ \x00\x7C\xC6\xC6\xDE\xDE\xDE\xC0\xC0\x7C\x00\x00\ \x00\x30\x78\xCC\xCC\xCC\xFC\xCC\xCC\xCC\x00\x00\ \x00\xFC\x66\x66\x66\x7C\x66\x66\x66\xFC\x00\x00\ \x00\x3C\x66\xC6\xC0\xC0\xC0\xC6\x66\x3C\x00\x00\ \x00\xF8\x6C\x66\x66\x66\x66\x66\x6C\xF8\x00\x00\ \x00\xFE\x62\x60\x64\x7C\x64\x60\x62\xFE\x00\x00\ \x00\xFE\x66\x62\x64\x7C\x64\x60\x60\xF0\x00\x00\ \x00\x3C\x66\xC6\xC0\xC0\xCE\xC6\x66\x3E\x00\x00\ \x00\xCC\xCC\xCC\xCC\xFC\xCC\xCC\xCC\xCC\x00\x00\ \x00\x78\x30\x30\x30\x30\x30\x30\x30\x78\x00\x00\ \x00\x1E\x0C\x0C\x0C\x0C\xCC\xCC\xCC\x78\x00\x00\ \x00\xE6\x66\x6C\x6C\x78\x6C\x6C\x66\xE6\x00\x00\ \x00\xF0\x60\x60\x60\x60\x62\x66\x66\xFE\x00\x00\ \x00\xC6\xEE\xFE\xFE\xD6\xC6\xC6\xC6\xC6\x00\x00\ \x00\xC6\xC6\xE6\xF6\xFE\xDE\xCE\xC6\xC6\x00\x00\ \x00\x38\x6C\xC6\xC6\xC6\xC6\xC6\x6C\x38\x00\x00\ \x00\xFC\x66\x66\x66\x7C\x60\x60\x60\xF0\x00\x00\ \x00\x38\x6C\xC6\xC6\xC6\xCE\xDE\x7C\x0C\x1E\x00\ \x00\xFC\x66\x66\x66\x7C\x6C\x66\x66\xE6\x00\x00\ \x00\x78\xCC\xCC\xC0\x70\x18\xCC\xCC\x78\x00\x00\ \x00\xFC\xB4\x30\x30\x30\x30\x30\x30\x78\x00\x00\ \x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x78\x00\x00\ \x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x78\x30\x00\x00\ \x00\xC6\xC6\xC6\xC6\xD6\xD6\x6C\x6C\x6C\x00\x00\ \x00\xCC\xCC\xCC\x78\x30\x78\xCC\xCC\xCC\x00\x00\ \x00\xCC\xCC\xCC\xCC\x78\x30\x30\x30\x78\x00\x00\ \x00\xFE\xCE\x98\x18\x30\x60\x62\xC6\xFE\x00\x00\ \x00\x3C\x30\x30\x30\x30\x30\x30\x30\x3C\x00\x00\ \x00\x00\x80\xC0\x60\x30\x18\x0C\x06\x02\x00\x00\ \x00\x3C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x3C\x00\x00\ \x10\x38\x6C\xC6\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\ \x30\x30\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\ \x00\xE0\x60\x60\x7C\x66\x66\x66\x66\xDC\x00\x00\ \x00\x00\x00\x00\x78\xCC\xC0\xC0\xCC\x78\x00\x00\ \x00\x1C\x0C\x0C\x7C\xCC\xCC\xCC\xCC\x76\x00\x00\ \x00\x00\x00\x00\x78\xCC\xFC\xC0\xCC\x78\x00\x00\ \x00\x38\x6C\x60\x60\xF8\x60\x60\x60\xF0\x00\x00\ \x00\x00\x00\x00\x76\xCC\xCC\xCC\x7C\x0C\xCC\x78\ \x00\xE0\x60\x60\x6C\x76\x66\x66\x66\xE6\x00\x00\ \x00\x18\x18\x00\x78\x18\x18\x18\x18\x7E\x00\x00\ \x00\x0C\x0C\x00\x3C\x0C\x0C\x0C\x0C\xCC\xCC\x78\ \x00\xE0\x60\x60\x66\x6C\x78\x6C\x66\xE6\x00\x00\ \x00\x78\x18\x18\x18\x18\x18\x18\x18\x7E\x00\x00\ \x00\x00\x00\x00\xFC\xD6\xD6\xD6\xD6\xC6\x00\x00\ \x00\x00\x00\x00\xF8\xCC\xCC\xCC\xCC\xCC\x00\x00\ \x00\x00\x00\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\ \x00\x00\x00\x00\xDC\x66\x66\x66\x66\x7C\x60\xF0\ \x00\x00\x00\x00\x76\xCC\xCC\xCC\xCC\x7C\x0C\x1E\ \x00\x00\x00\x00\xEC\x6E\x76\x60\x60\xF0\x00\x00\ \x00\x00\x00\x00\x78\xCC\x60\x18\xCC\x78\x00\x00\ \x00\x00\x20\x60\xFC\x60\x60\x60\x6C\x38\x00\x00\ \x00\x00\x00\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\ \x00\x00\x00\x00\xCC\xCC\xCC\xCC\x78\x30\x00\x00\ \x00\x00\x00\x00\xC6\xC6\xD6\xD6\x6C\x6C\x00\x00\ \x00\x00\x00\x00\xC6\x6C\x38\x38\x6C\xC6\x00\x00\ \x00\x00\x00\x00\x66\x66\x66\x66\x3C\x0C\x18\xF0\ \x00\x00\x00\x00\xFC\x8C\x18\x60\xC4\xFC\x00\x00\ \x00\x1C\x30\x30\x60\xC0\x60\x30\x30\x1C\x00\x00\ \x00\x18\x18\x18\x18\x00\x18\x18\x18\x18\x00\x00\ \x00\xE0\x30\x30\x18\x0C\x18\x30\x30\xE0\x00\x00\ \x00\x73\xDA\xCE\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x10\x38\x6C\xC6\xC6\xFE\x00\x00\x00\ \x00\x78\xCC\xCC\xC0\xC0\xC0\xCC\xCC\x78\x30\xF0\ \x00\xCC\xCC\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\ \x0C\x18\x30\x00\x78\xCC\xFC\xC0\xCC\x78\x00\x00\ \x30\x78\xCC\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\ \x00\xCC\xCC\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\ \xC0\x60\x30\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\ \x38\x6C\x6C\x38\xF8\x0C\x7C\xCC\xCC\x76\x00\x00\ \x00\x00\x00\x00\x78\xCC\xC0\xC0\xCC\x78\x30\xF0\ \x30\x78\xCC\x00\x78\xCC\xFC\xC0\xC0\x7C\x00\x00\ \x00\xCC\xCC\x00\x78\xCC\xFC\xC0\xC0\x7C\x00\x00\ \xC0\x60\x30\x00\x78\xCC\xFC\xC0\xC0\x7C\x00\x00\ \x00\x6C\x6C\x00\x78\x18\x18\x18\x18\x7E\x00\x00\ \x10\x38\x6C\x00\x78\x18\x18\x18\x18\x7E\x00\x00\ \x60\x30\x18\x00\x78\x18\x18\x18\x18\x7E\x00\x00\ \x00\xCC\x00\x30\x78\xCC\xCC\xFC\xCC\xCC\x00\x00\ \x78\xCC\xCC\x78\x78\xCC\xCC\xFC\xCC\xCC\x00\x00\ \x0C\x18\x30\xFC\xC4\xC0\xF8\xC0\xC4\xFC\x00\x00\ \x00\x00\x00\x00\xFE\x1B\x7F\xD8\xD8\xEF\x00\x00\ \x00\x3E\x78\xD8\xD8\xFE\xD8\xD8\xD8\xDE\x00\x00\ \x30\x78\xCC\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\ \x00\xCC\xCC\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\ \xC0\x60\x30\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\ \x30\x78\xCC\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\ \xC0\x60\x30\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\ \x00\x66\x66\x00\x66\x66\x66\x66\x3C\x0C\x18\xF0\ \xCC\x00\x78\xCC\xCC\xCC\xCC\xCC\xCC\x78\x00\x00\ \xCC\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x78\x00\x00\ \x00\x30\x30\x78\xCC\xC0\xC0\xCC\x78\x30\x30\x00\ \x3C\x66\x60\x60\x60\xFC\x60\x60\xC0\xFE\x00\x00\ \xCC\xCC\xCC\xCC\x78\xFC\x30\xFC\x30\x30\x00\x00\ \xF0\x88\x88\x88\xF0\x88\x9E\x8C\x8D\x86\x00\x00\ \x0E\x1B\x18\x18\x7E\x18\x18\x18\xD8\x70\x00\x00\ \x0C\x18\x30\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\ \x0C\x18\x30\x00\x78\x18\x18\x18\x18\x7E\x00\x00\ \x0C\x18\x30\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\ \x0C\x18\x30\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\ \x00\x76\xDC\x00\xF8\xCC\xCC\xCC\xCC\xCC\x00\x00\ \x76\xDC\x00\xC6\xE6\xF6\xDE\xCE\xC6\xC6\x00\x00\ \x00\x78\xCC\xCC\x7E\x00\xFE\x00\x00\x00\x00\x00\ \x00\x78\xCC\xCC\x78\x00\xFE\x00\x00\x00\x00\x00\ \x00\x30\x30\x00\x30\x60\xC0\xC0\xCC\x78\x00\x00\ \x00\x00\x00\x00\x00\xFC\xC0\xC0\xC0\x00\x00\x00\ \x00\x00\x00\x00\x00\xFC\x0C\x0C\x0C\x00\x00\x00\ \x00\x42\xC6\xCC\xD8\x30\x6E\xC3\x86\x0C\x1F\x00\ \x00\x63\xE6\x6C\x78\x37\x6F\xDB\xB3\x3F\x03\x00\ \x00\x30\x30\x00\x30\x30\x78\x78\x78\x30\x00\x00\ \x00\x00\x00\x00\x33\x66\xCC\xCC\x66\x33\x00\x00\ \x00\x00\x00\x00\xCC\x66\x33\x33\x66\xCC\x00\x00\ \x24\x92\x49\x24\x92\x49\x24\x92\x49\x24\x92\x49\ \x55\xAA\x55\xAA\x55\xAA\x55\xAA\x55\xAA\x55\xAA\ \x6D\xDB\xB6\x6D\xDB\xB6\x6D\xDB\xB6\x6D\xDB\xB6\ \x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\ \x18\x18\x18\x18\x18\xF8\x18\x18\x18\x18\x18\x18\ \x18\x18\x18\x18\xF8\x18\x18\xF8\x18\x18\x18\x18\ \x66\x66\x66\x66\x66\xE6\x66\x66\x66\x66\x66\x66\ \x00\x00\x00\x00\x00\xFE\x66\x66\x66\x66\x66\x66\ \x00\x00\x00\x00\xF8\x18\x18\xF8\x18\x18\x18\x18\ \x66\x66\x66\x66\xE6\x06\x06\xE6\x66\x66\x66\x66\ \x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\ \x00\x00\x00\x00\xFE\x06\x06\xE6\x66\x66\x66\x66\ \x66\x66\x66\x66\xE6\x06\x06\xFE\x00\x00\x00\x00\ \x66\x66\x66\x66\x66\xFE\x00\x00\x00\x00\x00\x00\ \x18\x18\x18\x18\xF8\x18\x18\xF8\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\xF8\x18\x18\x18\x18\x18\x18\ \x18\x18\x18\x18\x18\x1F\x00\x00\x00\x00\x00\x00\ \x18\x18\x18\x18\x18\xFF\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\xFF\x18\x18\x18\x18\x18\x18\ \x18\x18\x18\x18\x18\x1F\x18\x18\x18\x18\x18\x18\ \x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\ \x18\x18\x18\x18\x18\xFF\x18\x18\x18\x18\x18\x18\ \x18\x18\x18\x18\x1F\x18\x18\x1F\x18\x18\x18\x18\ \x66\x66\x66\x66\x66\x67\x66\x66\x66\x66\x66\x66\ \x66\x66\x66\x66\x67\x60\x60\x7F\x00\x00\x00\x00\ \x00\x00\x00\x00\x7F\x60\x60\x67\x66\x66\x66\x66\ \x66\x66\x66\x66\xE7\x00\x00\xFF\x00\x00\x00\x00\ \x00\x00\x00\x00\xFF\x00\x00\xE7\x66\x66\x66\x66\ \x66\x66\x66\x66\x67\x60\x60\x67\x66\x66\x66\x66\ \x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\ \x66\x66\x66\x66\xE7\x00\x00\xE7\x66\x66\x66\x66\ \x18\x18\x18\x18\xFF\x00\x00\xFF\x00\x00\x00\x00\ \x66\x66\x66\x66\x66\xFF\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\xFF\x00\x00\xFF\x18\x18\x18\x18\ \x00\x00\x00\x00\x00\xFF\x66\x66\x66\x66\x66\x66\ \x66\x66\x66\x66\x66\x7F\x00\x00\x00\x00\x00\x00\ \x18\x18\x18\x18\x1F\x18\x18\x1F\x00\x00\x00\x00\ \x00\x00\x00\x00\x1F\x18\x18\x1F\x18\x18\x18\x18\ \x00\x00\x00\x00\x00\x7F\x66\x66\x66\x66\x66\x66\ \x66\x66\x66\x66\x66\xE7\x66\x66\x66\x66\x66\x66\ \x18\x18\x18\x18\xFF\x00\x00\xFF\x18\x18\x18\x18\ \x18\x18\x18\x18\x18\xF8\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x1F\x18\x18\x18\x18\x18\x18\ \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\ \x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\ \xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\ \x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\ \xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x76\xDE\xCC\xCC\xDE\x76\x00\x00\ \x00\x78\xCC\xCC\xD8\xCC\xCC\xCC\xF8\xC0\x60\x00\ \x00\xFC\xCC\xCC\xC0\xC0\xC0\xC0\xC0\xC0\x00\x00\ \x00\xFE\x6C\x6C\x6C\x6C\x6C\x6C\x6C\x66\x00\x00\ \x00\xFC\xC4\x64\x60\x30\x60\x64\xC4\xFC\x00\x00\ \x00\x00\x00\x00\x7E\xC8\xCC\xCC\xCC\x78\x00\x00\ \x00\x00\x00\x00\x66\x66\x66\x66\x66\x7B\x60\xC0\ \x00\x00\x00\x76\xDC\x18\x18\x18\x18\x0E\x00\x00\ \x00\xFC\x30\x78\xCC\xCC\xCC\x78\x30\xFC\x00\x00\ \x00\x78\xCC\xCC\xCC\xFC\xCC\xCC\xCC\x78\x00\x00\ \x00\x7C\xC6\xC6\xC6\xC6\x6C\x6C\x6C\xEE\x00\x00\ \x00\x3C\x60\x30\x78\xCC\xCC\xCC\xCC\x78\x00\x00\ \x00\x00\x00\x76\xDB\xDB\xDB\x6E\x00\x00\x00\x00\ \x00\x00\x06\x7C\xDE\xD6\xF6\x7C\xC0\x00\x00\x00\ \x00\x3C\x60\xC0\xC0\xFC\xC0\xC0\x60\x3C\x00\x00\ \x00\x00\x78\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x00\x00\ \x00\x00\xFC\x00\x00\xFC\x00\x00\xFC\x00\x00\x00\ \x00\x00\x30\x30\xFC\x30\x30\x00\xFC\x00\x00\x00\ \x00\x60\x30\x18\x18\x30\x60\x00\xFC\x00\x00\x00\ \x00\x18\x30\x60\x60\x30\x18\x00\xFC\x00\x00\x00\ \x00\x00\x0E\x1B\x1B\x18\x18\x18\x18\x18\x18\x18\ \x18\x18\x18\x18\x18\x18\x18\xD8\xD8\x70\x00\x00\ \x00\x00\x30\x30\x00\xFC\x00\x30\x30\x00\x00\x00\ \x00\x00\x73\xDB\xCE\x00\x73\xDB\xCE\x00\x00\x00\ \x00\x3C\x66\x66\x66\x3C\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x1C\x1C\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\ \x00\x07\x04\x04\x04\x44\x64\x34\x1C\x0C\x00\x00\ \x00\xD8\x6C\x6C\x6C\x6C\x00\x00\x00\x00\x00\x00\ \x00\x78\x0C\x18\x30\x7C\x00\x00\x00\x00\x00\x00\ \x00\x00\x3C\x3C\x3C\x3C\x3C\x3C\x3C\x3C\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ " assert len(chars) == len(charset) * 12 glyphs = np.unpackbits(np.frombuffer(chars, np.uint8)).reshape(256, 12, 8) def render(text, scale): if isinstance(text, str): inds = [charset.index(c) if c in charset else 255 for c in text] else: inds = list(text) if len(inds) == 0: return np.array((), np.uint8) image = np.zeros((12, len(inds) * 8), np.uint8) for i, ind in enumerate(inds): a = i * 8 b = a + 8 # glyph = np.unpackbits(chars[a:b]) # BROKEN # glyph.shape = (8, 12) # image[:, a:b] = glyph image[:, a:b] = glyphs[ind] return image # TODO: optional flip horizontal and vertical kwargs. def render_to(text, image, *, x, y, scale=1, masked=0): # TODO: maybe return whether or not # the text had to be clipped within the image bounds? assert scale > 0 assert isinstance(scale, int) assert masked in (-1, 0, 1) text = render(text, scale) * 255 if scale > 1: text2 = np.repeat(text, scale) text2.shape = (text.shape[0], text.shape[1] * scale) x2 = x + text2.shape[1] if masked == 0: for yy in range(12): for s in range(scale): image[y + yy * scale + s, x:x2, ...] = text2[yy, :, None] elif masked == 1: for yy in range(12): mask = text2[yy, :] != 0 for s in range(scale): image[y + yy * scale + s, x:x2, ...][mask] = 255 elif masked == -1: for yy in range(12): mask = text2[yy, :] == 0 for s in range(scale): image[y + yy * scale + s, x:x2, ...][mask] = 0 else: x2 = x + text.shape[1] y2 = y + text.shape[0] if masked == 0: image[y:y2, x:x2, ...] = text[:, :, None] elif masked == 1: mask = text[:, :] != 0 image[y:y2, x:x2, ...][mask] = 255 elif masked == -1: mask = text[:, :] == 0 image[y:y2, x:x2, ...][mask] = 0 if __name__ == "__main__": from sys import stderr from base64 import b64encode glyphs = load("dwarf.png") for i, glyph in enumerate(glyphs): print(f"<== {i} ==>", file=stderr) for row in glyph: print("".join("#" if col else "." for col in row), file=stderr) packed = np.packbits(glyph) # 1 bit per pixel formatted = "".join(f"\\x{byte:02X}" for byte in packed) print(f'b"{formatted}",') # print() print(b64encode(glyphs.tobytes()))