-
Notifications
You must be signed in to change notification settings - Fork 0
/
encoder.py
140 lines (120 loc) · 4.13 KB
/
encoder.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from PIL import Image
import constants
import os
def generateQuadrants(arr):
quadrants = []
for i in range(0, len(arr), 16):
quadrants.append(decodeQuadrant(arr[i:i+16]))
return quadrants
def getColorPaletteIndexFromBits(b1, b2):
#0 0 W 000000000 0
#1 0 G 000000010 1
#0 1 D 000000001 2
#1 1 B 000000011 3
# Bitshift the bits of b2 to the left by 1. (00000001 << 1 = 00000010)
# Next, bitwise 'or' the new value of b2 with b1 (00000010 | 00000001 = 00000011)
#
#this will result in 4 unique outputs for each color index.
return b2 << 1 | b1
def decodeQuadrant(arr):
out = []
for i in range(0, len(arr), 2):
#each hex value represents 8 bits (and 8 pixels)
#get each byte and the byte after it
byte = format(arr[i], '08b')
nextByte = format(arr[i+1], '08b')
#for each bit in the byte, get the color index from it
#plus the bit in the same offset of the next byte.
for x in range(len(byte)): #always going to be 8 (8 bits in hex (byte) and thus 8 pixels in the quad)..
p1 = int(byte[x])
p2 = int(nextByte[x])
out.append(getColorPaletteIndexFromBits(p1, p2))
return out
def sortQuadrants(quadrants):
#you'd expect them to be sorted like:
# 0 1 2 3
# 4 5 6 7
# 8 9 10 11
# 12 13 14 15
#
#Every 4 quads seems to be sorted vertically then horizontally.
#but every 2 x 4 quads are organized horizontally...
#to draw the image, they should be sorted like below.
#(unless youve got a better optimization, so that we can skip this step)
quadrantCnt = len(quadrants)
ordered = []
print(quadrantCnt)
if quadrantCnt == 1 or quadrantCnt == 2:
# 8x8 8x16
# 0 0
# 1
ordered = quadrants #already sorted
elif quadrantCnt == 4:
# 16x16
# 0 2
# 1 3
ordered = [
quadrants[0],
quadrants[2],
quadrants[1],
quadrants[3]
]
elif quadrantCnt == 16:
# 32x32
# 0 2 8 10
# 1 3 9 11
# 4 6 12 14
# 5 7 13 15
ordered = [
quadrants[0],
quadrants[2],
quadrants[8],
quadrants[10],
quadrants[1],
quadrants[3],
quadrants[9],
quadrants[11],
quadrants[4],
quadrants[6],
quadrants[12],
quadrants[14],
quadrants[5],
quadrants[7],
quadrants[13],
quadrants[15]
]
return ordered
def exportImage(name, quadrants):
quadrantCnt = len(quadrants)
try:
imgWidth = constants.SPRITE_SIZES[quadrantCnt][0]
imgHeight = constants.SPRITE_SIZES[quadrantCnt][1]
except:
print(f'Size not supported. Quandrants: {quadrantCnt}')
return
print(f'Image size: {imgWidth}x{imgHeight}, (quadrants: {quadrantCnt})')
quadrantHorizontalCnt = int(imgWidth / constants.QUAD_SIZE)
#create new image and pixel map
img = Image.new('RGB', (imgWidth, imgHeight))
pixels = img.load()
#generate pixels for each quadrant
for quadIndex in range(quadrantCnt):
#quadrant coordinates
qx = int(quadIndex % quadrantHorizontalCnt) * constants.QUAD_SIZE
qy = int(quadIndex / quadrantHorizontalCnt) * constants.QUAD_SIZE
quadrant = quadrants[quadIndex]
#iterate each pixel in the quadrant
for pIndex in range(len(quadrant)):
#every quadrant is made of 64 pixels (8x8)
#get the pixel x and y
px = qx + int(pIndex % 8)
py = qy + int(pIndex / 8)
#set the pixel color based on the index value in the palette.
pixelIndex = quadrant[pIndex]
pixels[px, py] = constants.PALETTE[pixelIndex]
#finally, save the image.
try:
os.makedirs(constants.EXPORT_FOLDER)
except:# folder already most likely exists. fix your perms otherwise.
pass
img.save(f'{constants.EXPORT_FOLDER}/{name}.png')