两个文件都以 4 个字节的大数字开头;显然是后面数据的总大小。我忽略它,因为文件大小似乎是固定的。(此外,对于图像,其他重要数据,其宽度和高度,不存储在文件中。)
调色板
调色板是每通道 5 位的 BGR,最高位未使用。这两个字节以小端顺序存储。因此,转换为真彩色 RGB 是一个位移问题;你最终得到 16 个 RGB 颜色三元组。
图片
图像存储在 16 x 16 块中,每块 8 x 8 像素,每两个连续的像素被打包成一个字节,右像素在前。每个像素值的范围为 0..15,并立即映射到调色板。
要解压单个 8x8 块,只需要
for y in range(8):
for x in range(4):
print (img[4*y+x]])
这产生了一系列 2 像素数据。我发现在下面将每两个半字节立即解压缩为 2 个独立的像素更方便;然后就是在右 x 和 y 轴上循环以将整个图像重新组合成一个连贯的、线性的、128x128 像素位图。
下面的代码然后将每个像素的 RGB 值存储在真彩色 PNG 图像中;或者,您也可以将其保存为调色板 PNG 图像(或您喜欢的任何其他图像格式)。
Python 3.x 代码
此代码需要pypng. 将路径的固定部分调整为您的文件夹结构——它应该以斜线结尾。另存为cookie2png.py并从命令行调用
python cookie2png.py Rose/bu_strawberry_LZ.bin\bu_strawberry_anger
即,去掉部分_pal.bin,_spr.bin这样脚本就可以自己找到它们。
import sys,png
from struct import unpack
path = "/Sprites/Character files/"
# base = 'bu_strawberry2'
base = sys.argv[1]
with open (path+base+'_pal.bin', 'rb') as p:
pal = p.read()
pal = unpack('<I16H', pal)[1:]
pal = [bin(p)[2:].zfill(15) for p in pal]
rgb = [(int(p[10:15]+p[10:13],2),int(p[5:10]+p[5:8],2),int(p[0:5]+p[0:3],2)) for p in pal]
print ('rgb palette', *['%02x%02x%02x' % (r,g,b) for r,g,b in rgb])
with open (path+base+'_spr.bin', 'rb') as i:
img = i.read()
# Strip header
img = img[4:]
# Convert nibbles to bytes
img = [[b & 0x0f,b >> 4] for b in img]
# Unpack list
img = [b for a in img for b in a]
# Linearize image
target = []
for y in range(16):
for yy in range(8):
for x in range(16):
for xx in range(8):
target.append(rgb[img[16*64*y+64*x+8*yy+xx]])
# Convert from palettized into True color
target = [color for rgb in target for color in rgb]
# Split into rows, required by pypng
target = [target[i:i + 3*128] for i in range(0, len(target), 3*128)]
w = png.Writer(128, 128, greyscale=False, bitdepth=8)
with open(path+base+'.png', 'wb') as f:
w.write(f, target)
结果正如预期的那样。这是您的bu_strawberry,以及一些有趣的其他人:
