但是在整个过程中,hzc文件头中包含的原图片相关参数至关重要:毕竟立绘文件不可能和窗口一样大吧?所以我们回过头去分析hzc文件的文件头都包含了哪些有用的信息。
回顾一下,上面的背景图的hzc文件的文件头是这样的:
68 7A 63 31 00 F9 15 00 20 00 00 00 4E 56 53 47
00 01 00 00 20 03 58 02 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00
我们知道,原本的图片分辨率为800×600 即0x0320×0x0258 ;图片大小为1440000 ,也就是0x0015f900。仔细看看刚才的hzc文件的第一行,没错,文件头之后紧跟着的四位数是小端序整数,记录了压缩前文件大小。就在这四位小端序整数的正下方,记录了图片分辨率,这里就用2字节的小端序整数了。
再学习一下BMP文件的文件头组成。这种技术问题直接找百度百科词条即可[1]。如果是54字节的文件头,通常包含以下内容:
1.2字节的“BM”(仅考虑Windows系统)
2.4字节的文件总大小(包括像素数据和文件头)
3.4字节的0x00
4.4字节的小端序像素数据绝对偏移
5.4字节的小端序位图信息头长度(我们就认为是28 00 00 00就好)
6.两个4字节的小端序整数,分别记录图片的长和宽(也就是计算分辨率)
7.2字节的“0x01 0x00”
8.2字节,记录每个像素的位数。此处我们仅需考虑0x18与0x20两种即可,前者对应RGB,后者对应RGBA。这一位的信息影响每个像素对应的字节数。换言之我们可以通过分辨率和文件大小反推出这一位的值。
9.余下的字节是后续的相关内容,不过我们全都输入0x00即可,影响不大。
背景图用的是RGB,考虑到立绘图必然会出现透明部分,立绘图应该用RGBA,是否如此?我们打开一个立绘的hzc看看:


文件头是这样的:
68 7A 63 31 58 3C 2B 00 20 00 00 00 4E 56 53 47
00 01 01 00 A2 02 1B 04 C1 00 E2 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00
稍微对比一下,我们可以发现,除了已知的图片大小、分辨率的变量信息,还有一些不同。0x12位置处,立绘文件是0x01而背景图是0x00;0x18到0x1B位置,立绘文件有内容而背景图没有。先计算图片数据吧。大小为0x002B3C58=2833496字节;分辨率为674×1051;像素数为708374,即每个像素使用4个字节的数据,符合RGBA。这两处不同到底哪一个负责区分图片使用RGB还是RGBA?我倾向于0x12单字节控制。不过还是不确定,换一张立绘:


0x12位置为01,0x18到0x1B位置处内容不同。作出判断:0x12位置的值确定图片是24位或32位。那么把以上信息丢给D指导吧。
那么这会儿我们写好了一个,顺带一提在input指令后加上“.strip(‘”’)”可以支持拖动文件进cmd框从而减少处理工作(毕竟某些文件名真不好打出来)。试试背景图?可以。立绘呢?有点瑕疵,但GARbro弄出来的也一个样所以可以放着不管。还有表情呢?这回报错了。检查一下原因:


0x12位置出现了0x02,是新的内容。此外还有0x20也出现了不一样的内容。还是一样,先看图片数据。图片大小0x1f 0x9a 0x40=2071104字节。长0x86宽0xA8即分辨率为134×168。那么总的像素数为22512,算它是32位图,理论大小为90048字节,这可差远了。怎么回事呢?或许我们主动修改一下图片的长或者宽?总之我们把y_size改成刚好能装下的3864 = 0x0F 0x18,试试看:
(图片过长,考虑到观感就不放了,总之这里是很多个表情差分上下搭在一起)
呃,好多个爱丽丝(Wiz的主角アリス)的头。原来是hzc里面储存了多个表情差分,所以只考虑一张图的话大小完全对不上。这里总共有23张表情差分,刚好对得上0x20位置的0x17(16+7=23)。所以我们得加一条:如果在第19个字符发现了0x02,将图片数设置为第33个字符对应的数z,然后解zlib压缩并反转好了的那些数据要平均分为z组,每一组单独加一个一样的文件头。调整完毕,试试看:


顺利完成。