IMGV2
1. 介绍
IMGV2是IMG文件结构的第二个版本,广泛用于DNF中大部分的贴图文件,所有的UI(按钮、对话框、广告图片、loading画面、地下城选择框等等)、图标(比如装备、装扮、消耗品、地面物品)、标志(比如物品品级框、伤害数字、装备锁等等)、称号贴图都使用IMGV2。
在2016年之前,几乎所有DNF贴图都是IMGV2格式(少数是IMGV1格式),在那之后,时装贴图被IMGV4代替,技能特效贴图也逐渐被IMGV5代替。对现在的版本,IMGV2的时装和技能特效基本见不到了,但是IMGV2版本的补丁依然是生效的。
IMGV2的特点是可以兼容任意复杂的贴图,易于点阵操作;但图像数据块所占空间大,读取速度较慢。
2. 结构
IMGV2的结构如下表所示:
文件头 | 20字节字符串(注意空格)“Neople Img File ” | |||||||||||||||||||||||||
索引表大小 | 4字节,索引表所占空间。 | |||||||||||||||||||||||||
保留 | 4字节,为0。 | |||||||||||||||||||||||||
版本号 | 4字节,IMGV2文件结构中的版本号为2。 | |||||||||||||||||||||||||
索引表数目 | 4字节,索引表的表项(包括指向型和图片型) | |||||||||||||||||||||||||
索引表 | 索引表项1 | 由若干个索引项构成。索引项包括2种,指向型和图片型。图片型存储对应图片的各种信息,指向型只存储一个数据,即所指向的图片的帧号。
| ||||||||||||||||||||||||
索引表项2 | ||||||||||||||||||||||||||
索引表项3 | ||||||||||||||||||||||||||
索引表项4 | ||||||||||||||||||||||||||
…… | ||||||||||||||||||||||||||
贴图数据 | 图像数据块1 | 由首尾相接的图像数据块构成。 由于大部分图像数据由ZLIB进行压缩,因此经常以“0x78 0x9C”数据开头(但不可以其为标准作为图像数据块的起始点)。 指向型索引项不对应任何图像数据(即对应的图像数据大小为0)。 | ||||||||||||||||||||||||
图像数据块2 | ||||||||||||||||||||||||||
图像数据块3 | ||||||||||||||||||||||||||
…… |
3. 图像数据
关于ZLIB压缩的贴图数据,可以使用ZLIB官方提供的库来进行解压缩,网上有很多ZLIB的使用教程(编译和使用),我们一般只使用两个函数 compress(压缩)和uncompress(解压),都是简单的对字节流进行操作,这里不在赘述。ZLIB官方地址:http://www.zlib.net/。代码是完全开源和免费的。
对于IMGV2来说,以“0x78、0x9C”开头的数据解压出的数据就是对应的像素点阵数据,可以根据颜色系统来分解成对应的像素颜色数据,然后根据图像索引项内的宽和高(高其实没啥必要)来使其二维化。
4. 关于图像读取与指向帧
在系统读取(提取)所需要的贴图时,一般都先指定所要提取图片的帧号。所谓帧号就是IMG文件内图像按索引表顺序存放的一个有序序号。第一帧(第一个贴图)就是0号帧,第二帧就是1号帧,以此类推。
系统在通过帧号提取图片时,若帧号索引项是图片索引项,就会根据在此之前的图片索引项内图像数据大小来跳过特定的数据,从而找到对应图片索引项的图片数据的起点。然后根据图片索引项内的图像数据大小来提取出整个图像数据块,然后对这个图像数据块进行解压(如果需要的话),通过颜色系统转换成点阵数据,就可以直接显示了。
若帧号索引项是指向型索引项(也就是指向帧),则系统通过该索引项的第二字节,也就是指向帧号来寻找对应的索引项,倘若对应的索引项依然是指向型索引项,则会继续寻找下去,直到找到图像索引项为止,然后根据上述的过程提取对应的图片。
当多个帧号指向同一图片时,指向型索引项允许其不需要存储相同的数据,因此极大地节省了IMG文件的空间。但是,这也产生了一个问题,即指向型索引项有可能像链表那样,指向型索引项指向了一个无意义或者并不存在的索引项(例如指向-1);或者甚至地,产生有向闭环结构,最简单的情形就是指向型索引项指向自己。前者会使界面产生红X,甚至导致严重的贴图错误;后者则更严重,使得系统不断地尝试进行贴图读取,进而使游戏直接崩溃(因而也有些人用EX制作整人补丁,比如深渊一出SS读取史诗特效的时候就游戏崩溃)。因此在使用指向型索引项的时候,最好能避免其指向其他的指向型索引项。
5. 增加一个贴图的流程
增加一个贴图,需要修改3个内容:首先,是文件开头的索引表数目和索引表大小要增加;其次,索引表的里面的指定帧号对应的位置要添加出新的图片数据的索引项;最后,根据指定帧号和对应位置在图像数据块中间插入目标图片数据(当然,要使用ZLIB进行压缩)。
值得注意的是,不像NPK内的IMG索引表,由于IMG内的图像索引表内没有存储偏移量数据,所以在对单个的IMG数据进行增加贴图操作时,几乎除了这三个部分之外都不需要改动,但如果使用的用于存储图像数据系列的数据结构(这些数据结构一般是EX开发人员自定义的)内部含有偏移量数据,最好重新读取IMG以修正这些变量。