はじめに
processingにおけるファイルの読み書きは、バイト配列やテキストなら単純にできますが、float型の読み書きがちょっと戸惑ったので、メモします。
HDRI画像のように32bit深度の画像データを読み書きしたいのですが、最低限の機能を自前で実現するための準備です。
説明
float型は4バイトあるため、そのままでは、読み書きができません。シフト演算などを駆使して、byte[4]に変換して書き込んだり、intに変換してから、byte[4]に変換して書き込んだり、といった記事が多いのですが(floatToIntBits)、もうちょっとシンプルに書けないか、試行錯誤した結果です。byte[4]に変換すると、リトルエンディアン、ビックエンディアン問題も気にしなくてはいけなくなると思います。
javaのFileOutputStreamやFileInputStreamを使ってみたものの、ファイルの生成ができなかったので、processingのcreateOutputでファイル作成します。javaのDataOutputStreamとDataInputStreamには、float型を直接読み書きする命令があり、これが便利そうなので使いました。とてもシンプルに書けたと思います。
ソースコード
float型の変数をout.datに保存して、
out.datを開き、floatを読み込んで、表示します。
import java.io.*;
// write
float f = 3.1415926535f;
try{
OutputStream os = createOutput("out.dat");
DataOutputStream dos = new DataOutputStream(os);
dos.writeFloat(f);
dos.flush();
dos.close();
}catch(IOException e){
e.printStackTrace();
}
// load
float f2 = 0f;
try{
InputStream is = createInput("out.dat");
DataInputStream dis = new DataInputStream(is);
f2 = dis.readFloat();
dis.close();
}catch(IOException e){
e.printStackTrace();
}
println(f2);
exit();
画像のような2次元配列の場合、以下のようになります。
import java.io.*;
// write
float[][] f = new float[256][256];
for (int y=0; y<256; y++) {
for (int x=0; x<256; x++) {
f[x][y] = sin(x)*sin(y);
}
}
try {
OutputStream os = createOutput("out.dat");
DataOutputStream dos = new DataOutputStream(os);
for (int y=0; y<256; y++) {
for (int x=0; x<256; x++) {
dos.writeFloat(f[x][y]);
}
}
dos.flush();
dos.close();
}
catch(IOException e) {
e.printStackTrace();
}
// load
float[][] f2 = new float[256][256];
try {
InputStream is = createInput("out.dat");
DataInputStream dis = new DataInputStream(is);
for (int y=0; y<256; y++) {
for (int x=0; x<256; x++) {
f2[x][y] = dis.readFloat();
}
}
dis.close();
}
catch(IOException e) {
e.printStackTrace();
}
exit();