-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathsprites2bitmap.py
executable file
·123 lines (94 loc) · 3.57 KB
/
sprites2bitmap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python3
'''
Convert a sprite sheet image to python a module for use with indexed bitmap method.
Sprite sheet width and height should be a multiple of sprite width and height. There
should be no extra pixels between sprites. All sprites will share the same palette.
Usage:
sprites2bitmap image_file spite_width sprite_height bits_per_pixel >sprites.py
MicroPython:
import sprites
... tft config and init code ...
tft.bitmap(sprites, x, y, index)
'''
from os import setpriority
from PIL import Image
import argparse
def main():
parser = argparse.ArgumentParser(
prog='imgtobitmap',
description='Convert image file to python module for use with bitmap method.')
parser.add_argument(
'image_file',
help='Name of file containing image to convert')
parser.add_argument(
'sprite_width',
type=int,
help='width of sprites in pixels')
parser.add_argument(
'sprite_height',
type=int,
help='height of sprites in pixels')
parser.add_argument(
'bits_per_pixel',
type=int,
choices=range(1, 9),
default=1,
metavar='bits_per_pixel',
help='The number of bits to use per pixel (1..8)')
args = parser.parse_args()
bits = args.bits_per_pixel
img = Image.open(args.image_file)
img = img.convert("P", palette=Image.ADAPTIVE, colors=2**bits)
palette = img.getpalette() # Make copy of palette colors
# For all the colors in the palette
colors = []
for color in range(1 << bits):
# get rgb values and convert to 565
color565 = (
((palette[color*3] & 0xF8) << 8) |
((palette[color*3+1] & 0xFC) << 3) |
((palette[color*3+2] & 0xF8) >> 3))
# swap bytes in 565
color = ((color565 & 0xff) << 8) + ((color565 & 0xff00) >> 8)
# append byte swapped 565 color to colors
colors.append(f'{color:04x}')
image_bitstring = ''
max_colors = 1 << bits
bitmaps = 0
# Run through the image and create a string with the ascii binary
# representation of the color of each pixel.
for y in range(0, img.height, args.sprite_height):
for x in range(0, img.width, args.sprite_width):
bitmaps += 1
for yy in range(y, y + args.sprite_height):
for xx in range(x, x + args.sprite_width):
pixel = img.getpixel((xx, yy))
color = pixel
image_bitstring += ''.join(
'1' if (color & (1 << bit - 1)) else '0' for bit in range(bits, 0, -1))
bitmap_bits = len(image_bitstring)
# Create python source with image parameters
print(f'BITMAPS = {bitmaps}')
print(f'HEIGHT = {args.sprite_height}')
print(f'WIDTH = {args.sprite_width}')
print(f'COLORS = {max_colors}')
print(f'BITS = {bitmap_bits}')
print(f'BPP = {bits}')
print('PALETTE = [', sep='', end='')
for color, rgb in enumerate(colors):
if color:
print(',', sep='', end='')
print(f'0x{rgb}', sep='', end='')
print("]")
# Run though image bit string 8 bits at a time
# and create python array source for memoryview
print("_bitmap =\\", sep='')
print("b'", sep='', end='')
for i in range(0, bitmap_bits, 8):
if i and i % (16*8) == 0:
print("'\\\nb'", end='', sep='')
value = image_bitstring[i:i+8]
color = int(value, 2)
print(f'\\x{color:02x}', sep='', end='')
print("'\nBITMAP = memoryview(_bitmap)")
main()