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++ で作成) は、1 ~ 4 ではなく -256 ~ 511 の範囲を表示します。私のコードに明らかなバグはありますか?
編集: base64 でエンコードされたデータは次のようになります。
ラアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアル
編集 2 : float の配列を取り、Byte 配列に変換し、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