replace binary_image_palette with color_convert
This commit is contained in:
parent
25156e2fc0
commit
9b7f0e8bf4
@ -1,78 +0,0 @@
|
|||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
def round_up_palette_size(palette_size):
|
|
||||||
assert palette_size != 0, (name, palette_size)
|
|
||||||
if palette_size <= 4:
|
|
||||||
return 4
|
|
||||||
elif palette_size <= 16:
|
|
||||||
return 16
|
|
||||||
elif palette_size <= 256:
|
|
||||||
return 256
|
|
||||||
else:
|
|
||||||
assert False, palette_size
|
|
||||||
|
|
||||||
def pixels_per_byte(palette_size):
|
|
||||||
if palette_size == 4:
|
|
||||||
return 4
|
|
||||||
elif palette_size == 16:
|
|
||||||
return 2
|
|
||||||
elif palette_size == 256:
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
assert False, palette_size
|
|
||||||
|
|
||||||
def pack_one_byte(pixels, index, colors, palette_size):
|
|
||||||
color_count = len(colors)
|
|
||||||
num = pixels_per_byte(palette_size)
|
|
||||||
shift = 8 // num
|
|
||||||
byte = 0
|
|
||||||
i = 0
|
|
||||||
while num > 0:
|
|
||||||
px, alpha = pixels[index]
|
|
||||||
if alpha == 0 and color_count < palette_size:
|
|
||||||
px = color_count
|
|
||||||
assert px < palette_size
|
|
||||||
byte |= px << (shift * i)
|
|
||||||
index += 1
|
|
||||||
i += 1
|
|
||||||
num -= 1
|
|
||||||
return [byte], index
|
|
||||||
|
|
||||||
def pack_one_texel(pixels, index, colors, palette_size):
|
|
||||||
px, alpha = pixels[index]
|
|
||||||
return
|
|
||||||
|
|
||||||
def pack_pixels(pixels, width, height, colors, palette_size):
|
|
||||||
index = 0
|
|
||||||
with open(sys.argv[2], 'wb') as f:
|
|
||||||
while index < (width * height):
|
|
||||||
byte_list, index = pack_texel(pixels, index, colors, palette_size)
|
|
||||||
f.write(bytes(byte))
|
|
||||||
|
|
||||||
def pack_palette(colors, palette_size):
|
|
||||||
with open(sys.argv[2], 'wb') as f:
|
|
||||||
for color in colors:
|
|
||||||
out = argb1555(255, *color)
|
|
||||||
f.write(struct.pack('<H', out))
|
|
||||||
if len(colors) < palette_size:
|
|
||||||
# transparent color
|
|
||||||
print('pack transparency at ix', len(colors))
|
|
||||||
out = argb1555(0, 0, 0, 0)
|
|
||||||
f.write(struct.pack('<H', out))
|
|
||||||
|
|
||||||
with Image.open(sys.argv[1]) as im:
|
|
||||||
assert im.mode == "P"
|
|
||||||
width, height = im.size
|
|
||||||
colors = list(im.palette.colors)
|
|
||||||
pixels = list(im.convert("PA").getdata())
|
|
||||||
|
|
||||||
palette_size = round_up_palette_size(len(colors))
|
|
||||||
if sys.argv[2].endswith('.data'):
|
|
||||||
pack_pixels(pixels, width, height, len(colors), palette_size)
|
|
||||||
elif sys.argv[2].endswith('.pal'):
|
|
||||||
pack_palette(colors, palette_size)
|
|
||||||
else:
|
|
||||||
assert False, sys.argv[2]
|
|
92
color_convert.py
Normal file
92
color_convert.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
class color_format:
|
||||||
|
def gbgr1555(r, g, b, a): # nintendo ds
|
||||||
|
r5 = (r >> 3) & 31
|
||||||
|
g6 = (g >> 3) & 31
|
||||||
|
g6_l = (g >> 2) & 1
|
||||||
|
b5 = (b >> 3) & 31
|
||||||
|
return (g6_l << 15) | (b5 << 10) | (g6 << 5) | (r5 << 0)
|
||||||
|
|
||||||
|
def argb4444(r, g, b, a):
|
||||||
|
a4 = (a >> 4) & 15
|
||||||
|
r4 = (r >> 4) & 15
|
||||||
|
g4 = (g >> 4) & 15
|
||||||
|
b4 = (b >> 4) & 15
|
||||||
|
return (a4 << 12) | (r4 << 8) | (g4 << 4) | (b4 << 0)
|
||||||
|
|
||||||
|
def argb1555(r, g, b, a):
|
||||||
|
a1 = (a >> 7) & 1
|
||||||
|
r5 = (r >> 3) & 31
|
||||||
|
g5 = (g >> 3) & 31
|
||||||
|
b5 = (b >> 3) & 31
|
||||||
|
return (a1 << 15) | (r5 << 10) | (g5 << 5) | (b5 << 0)
|
||||||
|
|
||||||
|
def rgb565(r, g, b, a):
|
||||||
|
r5 = (r >> 3) & 31
|
||||||
|
g6 = (g >> 2) & 63
|
||||||
|
b5 = (b >> 3) & 31
|
||||||
|
return (r5 << 11) | (g5 << 5) | (b5 << 0)
|
||||||
|
|
||||||
|
def from_string(s):
|
||||||
|
return dict([
|
||||||
|
("gbgr1555", color_format.gbgr1555),
|
||||||
|
("argb4444", color_format.argb4444),
|
||||||
|
("argb1555", color_format.argb1555),
|
||||||
|
("rgb565", color_format.rgb565),
|
||||||
|
])[s]
|
||||||
|
|
||||||
|
in_file = sys.argv[1]
|
||||||
|
format = sys.argv[2]
|
||||||
|
out_file = sys.argv[3]
|
||||||
|
|
||||||
|
palette = None
|
||||||
|
|
||||||
|
with Image.open(in_file) as im:
|
||||||
|
width, height = im.size
|
||||||
|
if not im.palette:
|
||||||
|
pixels = list(im.convert("RGBA").getdata())
|
||||||
|
else:
|
||||||
|
pixels = list(im.convert("P").getdata())
|
||||||
|
palette = list(im.palette.colors)
|
||||||
|
|
||||||
|
has_alpha = False
|
||||||
|
convert = color_format.from_string(format)
|
||||||
|
|
||||||
|
def convert_colors(f, colors):
|
||||||
|
for color in colors:
|
||||||
|
value = convert(*color)
|
||||||
|
f.write(struct.pack("<H", value))
|
||||||
|
|
||||||
|
if palette is None:
|
||||||
|
with open(out_file, 'wb') as f:
|
||||||
|
convert_colors(f, pixels)
|
||||||
|
else:
|
||||||
|
with open(out_file, 'wb') as f:
|
||||||
|
if len(palette) <= 4:
|
||||||
|
for i in range(len(pixels) // 4):
|
||||||
|
a = pixels[i * 4 + 0]
|
||||||
|
b = pixels[i * 4 + 1]
|
||||||
|
c = pixels[i * 4 + 2]
|
||||||
|
d = pixels[i * 4 + 3]
|
||||||
|
assert a <= 3 and b <= 3 and c <= 3 and d <= 3, (a, b, c, d)
|
||||||
|
pixel = (d << 6) | (c << 4) | (b << 2) | (a << 0)
|
||||||
|
f.write(struct.pack("<B", pixel))
|
||||||
|
elif len(palette) <= 16:
|
||||||
|
for i in range(len(pixels) // 2):
|
||||||
|
a = pixels[i * 2 + 0]
|
||||||
|
b = pixels[i * 2 + 1]
|
||||||
|
assert a <= 15 and b <= 15, (a, b)
|
||||||
|
pixel = (b << 4) | (a << 0)
|
||||||
|
f.write(struct.pack("<B", pixel))
|
||||||
|
elif len(palette) <= 256:
|
||||||
|
for pixel in pixels:
|
||||||
|
assert pixel <= 255
|
||||||
|
f.write(struct.pack("<B", pixel))
|
||||||
|
else:
|
||||||
|
assert False, len(palette)
|
||||||
|
with open(out_file + '.pal', 'wb') as f:
|
||||||
|
convert_colors(f, [(*c, 255) for c in palette])
|
Loading…
x
Reference in New Issue
Block a user