Я пишу свой собственный писатель для файлов VTK XML, используя F #. Файл 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 данные выглядят так:
LAAAAAABAAAA ///// wEAAAAAAAAADwEAAAAEAAAACAEAAAACAAAAAwAAAAQAAAAL
EDIT 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