0

这是 Vray 的 .vrscene 文件的格式说明:http: //spot3d.com/vray/help/maya/sdk22/vrscene_format.html

我对有关“压缩十六进制列表”的段落感兴趣。据说压缩列表等于标题(“ZIPB”)+未压缩大小+压缩大小+ zlib压缩字符串。

例如,在我的 .vrscene 中,我有这样的压缩列表:“ZIPB2C01000015000000e7X81OT0TG4S5ENN3D8Z8IVAPODONF7EA”

这意味着“e7X81OT0TG4S5ENN3D8Z8IVAPODONF7EA”——zlib 压缩字符串。但我不知道如何解压它。当我进行 Base64 解码时,我收到标头 0x7bb5。我不知道这样的标题。也许我不应该使用 Base64 而应该做其他事情?

4

2 回答 2

2

所以我知道这是旧的,但这里的信息足以让我找到一个解决方案,唯一的区别是我有一个来自不同 vrscene 文件的不同压缩列表。

正如您所建立的,您需要从字符串中删除前 20 个字符,因为它们只是 vray 使用的描述符,而不是压缩数据的一部分。

import base64, zlib

data = "ZIPCB81900003C000000eAHt0iERAAAMxLDC9694MkYCaqCXVZMHDDDAAAMMMMAAAwwwwAADDDDAAAMMMMAAAwwwwMC7gQMbojNx"
encoded_data = data[20:] #"eAHt0iERAAAMxLDC9694MkYCaqCXVZMHDDDAAAMMMMAAAwwwwAADDDDAAAMMMMAAAwwwwMC7gQMbojNx"
compressed_data = base64.b64decode(encoded_data)
hex_data = zlib.decompress(compressed_data)
# b'\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00...'

一旦你在这一点上,你就有了未经任何压缩的原始十六进制列表。如果您想将其转换为可读的 Python 数据类型,您可以使用 struct 来解包它们,具体取决于列表中存储的数据类型。

进一步阅读链接的文档解释说,所有这些列表都存储为每个条目 4 个字节(在文档中写为 8 个半字节,但就 python 而言,它只有 4 个字节)。有了这些信息,我们可以确定列表中的条目数应该是 hex_data / 4 的长度,并构建一个结构格式字符串,该字符串将立即解包整个列表。

import struct

#I have a list of ints as my example, but for floats you could use "f" instead
format = "i" * int(len(hex_data)/4)
values = struct.unpack(format, hex_data)
# [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ...]

还有颜色列表和向量列表,但它们只是需要展开的浮动列表。

vectors = []
for i in range(0, int(len(values)), 3):
    vectors.append(tuple(values[i:i+3]))

由于此方法似乎适用于到目前为止我遇到的所有压缩十六进制列表,因此您最初尝试从中解析数据的文件似乎存在问题,或者开发人员正在使用编码使用 base64 以外的方法,但从那时起就采用了 base64 编码(也许这就是我的文件中出现“ZIPC”而不是您的示例中的“ZIPB”的原因)。

于 2019-08-22T03:31:10.997 回答
0

文档说十六进制,但您提供的字符串有其他字符。它可能不是 base64,因为您在开始时没有得到有效的zlib标头。(顺便说一句, 0x7b 0xb5当我用 base64 解码它时,我得到的不是你得到的。但无论哪种方式,它都不是 zlib 标头。)你有更好的格式描述来源吗?

数据必须是高度可压缩的,例如全为零,因为它显然从 4140 字节变为 21 字节。

于 2012-08-08T20:40:15.433 回答