Created
January 6, 2022 14:03
-
-
Save TomoshibiAkira/782bbe57bd5e77ddbf0836a63a107e04 to your computer and use it in GitHub Desktop.
A Python script for converting images to AWBMv2 (Award BIOS Bitmap V2).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import argparse | |
import numpy as np | |
from PIL import Image | |
# Format description from: http://fileformats.archiveteam.org/wiki/Award_BIOS_logo | |
MAGIC = b'AWBM' | |
PALMAGIC = b'RGB ' | |
def parse(): | |
parser = argparse.ArgumentParser(description='img2awbmv2') | |
parser.add_argument('file') | |
parser.add_argument('--format', '-f', | |
default='auto', choices=['auto', '4', '8'], | |
help='use 4 or 8-bit variant. default: auto (deduce from the input image)') | |
parser.add_argument('--save', '-s', default='') | |
args = parser.parse_args() | |
return args | |
def main(args): | |
assert os.path.exists(args.file), "File not found!" | |
if len(args.save) == 0: | |
args.save = os.path.basename( | |
os.path.splitext(args.file)[0]+'.awbm', | |
) | |
if os.path.dirname(args.save) != '': | |
os.makedirs(os.path.dirname(args.save), exist_ok=True) | |
# read image | |
im = Image.open(args.file) | |
nim = np.asarray(im) | |
if nim.ndim == 2: | |
nim = nim[:, :, None] | |
unique_colors = np.unique(nim.reshape(-1, nim.shape[-1]), axis=0) | |
# detect colors | |
if args.format == 'auto': | |
if unique_colors.shape[0] <= 16: | |
colors = 16 | |
else: | |
colors = 256 | |
print ('Total {} unique colors found, using {} colors.'.format( | |
unique_colors.shape[0], colors | |
)) | |
elif args.format == '4': | |
colors = 16 | |
elif args.format == '8': | |
colors = 256 | |
sw = np.uint16(im.width).tobytes() | |
sh = np.uint16(im.height).tobytes() | |
pim = im.convert('P', palette=Image.ADAPTIVE, colors=colors) | |
# RGB palette | |
palette = np.asarray(pim.getpalette()[:colors*3], dtype=np.uint8) // 4 | |
if colors == 16: # 4bit | |
# convert to BGR | |
palette = palette.reshape(16, 3)[:, ::-1].reshape(-1) | |
# preparing data | |
npim = np.asarray(pim) | |
assert npim.ndim == 2 | |
cmp = 0x1 | |
fs = [] | |
for _ in range(4): | |
f = np.packbits(npim & cmp, axis=-1) | |
fs.append(f) | |
cmp = cmp << 1 | |
data = np.concatenate(fs, axis=1).tobytes() | |
else: # 8bit | |
data = pim.tobytes() | |
assert len(data) == im.width * im.height | |
# assemble | |
paldata = palette.tobytes() | |
with open(args.save, mode='wb') as f: | |
f.write(MAGIC) | |
f.write(sw) | |
f.write(sh) | |
f.write(data) | |
f.write(PALMAGIC) | |
f.write(paldata) | |
print ('Saved to {}.'.format(args.save)) | |
if __name__ == '__main__': | |
args = parse() | |
main(args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some quirks and tips: