Wolfram CDF Playerでローカルファイルの読み込みと書き込みを行う
Wolfram CDF Player を汎用するにあるように、 CDF PlayerでもJ/Linkを使えばローカルファイルの読み込み、書き込みができる(※CDFファイルの作成にはMathematicaが必要)。
上記リンク先ではテキストファイルを読み込む例が載っているが、バイナリファイルとして読み込んでImportString
を使えば、
Mathematicaが対応している形式すべてのファイルを読み込むことができる。
J/Linkでバイナリファイルを読み込むときのポイントとしては、
"[B"
というクラス名でbyte型の配列を作ってBufferedInputStream.read(byte[])
で一気に読み込むことで高速化- 読み込んだbyte[]がMathematicaに入った時に符号付き整数で扱われるため、
FromCharacterCode
に突っ込む前に0〜255になるように修正
が挙げられる。
一方、CDF PlayerではExport
のみならずExportString
が使えない(ImportString
は使えるのに)ので、書き込むほうは不自由が残る。
ここではテキストと画像(BMP、PNG、JPEG)に限って保存する関数を作ってみた。
ImportWithJLink[filepath_?(FileExistsQ[FindFile[#]] &), format_] := (
Needs["JLink`"];
JLink`InstallJava[];
JLink`JavaBlock[
Module[{br, byte, result},
br = JLink`JavaNew["java.io.BufferedInputStream",
JLink`JavaNew["java.io.FileInputStream", FindFile@filepath]];
byte = JLink`JavaNew["[B", {FileByteCount[FindFile@filepath]}];
br@read[byte];
result =
ImportString[
FromCharacterCode[
JLink`JavaObjectToExpression[byte] /. x_?Negative :> x + 256],
format];
br@close[];
result]]);
ExportWithJLink[filepath_, string_String, format : "Text"] := (
Needs["JLink`"];
JLink`InstallJava[];
JLink`JavaBlock[
Module[{bw},
bw = JLink`JavaNew["java.io.BufferedWriter",
JLink`JavaNew["java.io.FileWriter", filepath]
];
bw@write[string];
bw@close[];
filepath
]
]);
ExportWithJLink[filepath_, image_, format : "PNG" | "BMP" | "JPG"] := (
Needs["JLink`"];
JLink`InstallJava[];
JLink`JavaBlock[
JLink`LoadJavaClass["javax.imageio.ImageIO"];
JLink`LoadJavaClass["java.awt.image.BufferedImage"];
Module[{img, bi, width, height},
img = Rasterize[image];
{width, height} = ImageDimensions[img];
bi = JLink`JavaNew["java.awt.image.BufferedImage",
width, height, java`awt`image`BufferedImage`TYPEUINTUBGR
];
bi@setRGB[0, 0, width, height,
Flatten[
Apply[(#1*2^16 + #2*2^8 + #3) &,
ImageData[img, "Byte"], {2}]],
0, width];
If[javax`imageio`ImageIO`write[bi, format,
JLink`JavaNew["java.io.File", filepath]],
filepath, $Failed]
]
]);
例
読み込み
img = ImportWithJLink["ExampleData/lena.tif", "TIFF"]
書き込み
file = FileNameJoin[{$TemporaryDirectory, "testfile.webp"}];
ExportWithJLink[file, img, "PNG"];
Import[file]