72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
import os
|
|
import sys
|
|
import io
|
|
|
|
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)
|
|
print(len(buf))
|
|
|
|
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 bpp == 1:
|
|
assert px in {255, 0}, px
|
|
index = int(px != 0)
|
|
else:
|
|
index = intensity_to_index(px)
|
|
assert index < (2 ** bpp), index
|
|
|
|
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
|
|
|
|
tmp = io.BytesIO()
|
|
|
|
for in_path in sys.argv[3:]:
|
|
print(in_path)
|
|
im = Image.open(in_path)
|
|
buf = convert(im, bpp)
|
|
if 'NBPP_DEBUG' in os.environ:
|
|
debug(buf, bpp)
|
|
tmp.write(buf)
|
|
|
|
with open(out_path, 'wb') as f:
|
|
f.write(tmp.getvalue())
|