我正在使用 F# 为 VTK XML 文件编写自己的编写器。VTK 文件需要二进制数据的 base64 编码,以及此处描述的标头。
...所以二进制数据必须是 base64 编码的。此外,数据前面还有一个标头;它是一个 32 位整数,包含数据长度(以字节为单位)。此标头是单独编码的。所以在伪代码中,数据输出看起来像这样(总是没有空格或换行符!)
我的代码如下所示:
let toBase64 (v: int []) =
use ms = new System.IO.MemoryStream()
let s = System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
s.Serialize(ms, v)
let b = ms.ToArray()
let len = System.BitConverter.GetBytes b.Length
System.Convert.ToBase64String len + System.Convert.ToBase64String b
然而,结果是不正确的。对于以下输入:
toBase64 [| 1; 2; 3; 4 |]
ParaView(用 C++ 编写)显示范围 -256 到 511 而不是 1 到 4。您在我的代码中看到任何明显的错误吗?
编辑:我的 base64 编码数据如下所示:
LAAAAAAAAAAAA/////wEAAAAAAAAADwEAAAAEAAAACAEAAAACAAAAAAwAAAAQAAAAL
编辑 2:我附上了我的解决方案,它采用浮点数组并将其转换为字节数组,使用 Ionic.Zip.dll ZLib 对其进行压缩并将其转换为 base64 字符串。该函数适用于 VTK XML 文件。
let toZlib (v: float []) =
use msSinkCompressed = new System.IO.MemoryStream()
let zOut = new ZlibStream(msSinkCompressed, CompressionMode.Compress, CompressionLevel.Default, true)
for i in v do
let bytes = System.BitConverter.GetBytes i
zOut.Write(bytes, 0, bytes.Length)
zOut.Flush()
zOut.Close()
let comprBytes = msSinkCompressed.ToArray()
let header =
let blocks = System.BitConverter.GetBytes 1
let len = System.BitConverter.GetBytes (v.Length * 8)
let comprLen = System.BitConverter.GetBytes comprBytes.Length
Array.append(Array.append (Array.append blocks len) len) comprLen
System.Convert.ToBase64String header + System.Convert.ToBase64String comprBytes