import os import sys from PIL import Image from palette import intensity_to_index cell_width = 16 cell_height = 16 def convert(image, bpp): assert bpp in {8, 4, 2}, bpp bits_per_byte = 8 px_per_byte = bits_per_byte // bpp px_per_row = cell_width bytes_per_row = (px_per_row // px_per_byte) assert image.mode == 'L', image.mode width, height = image.size buf = bytearray(width * height // px_per_byte) for cell_y in range(height//cell_height): cell_y_start = cell_y * bytes_per_row * cell_height for cell_x in range(width//cell_width): cell_x_start = cell_y_start + bytes_per_row * cell_x for y in range(cell_height): for x in range(cell_width): px = im.getpixel((cell_x * cell_width + x, cell_y * cell_height + y)) index = intensity_to_index(px) buf_ix = cell_x_start + x//px_per_byte + y * bytes_per_row buf[buf_ix] |= (index << bpp * ((px_per_byte - 1) - (x % px_per_byte))) return buf # (pixels/row) # ------------ * # (pixels/byte) def debug(buf, bpp): assert bpp in {8, 4, 2}, bpp bits_per_byte = 8 px_per_byte = bits_per_byte // bpp px_per_row = cell_width bytes_per_row = (px_per_row // px_per_byte) bit_mask = (2 ** bpp) - 1 for row in range(len(buf) // bytes_per_row): for x in range(bytes_per_row): px = buf[row * bytes_per_row + x] for shift in reversed(range(px_per_byte)): print((px >> (shift * bpp)) & bit_mask, end='') print() if (row % cell_height == (cell_height - 1)): print() bpp = int(sys.argv[1]) out_path = sys.argv[2] in_paths = sys.argv[3:] assert len(sys.argv) >= 4, sys.argv with open(out_path, 'wb') as f: for in_path in in_paths: im = Image.open(in_path) buf = convert(im, bpp) if 'NBPP_DEBUG' in os.environ: debug(buf, bpp) f.write(buf)