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