こんにちは。
今回はファイルの読み込みの話です。
これまでに画像とテキストの保存方法を取り上げてきました。
processingの備忘録 -png、gifの生成- - プログラミングの備忘録
processingの備忘録 -txt、csvの生成- - プログラミングの備忘録
テキスト編の最後でも書きましたが、保存ができるようになったら今度は読み込みもできるようになりたいところ。
processingは"お絵かきソフト"なので、画像を取り込んで編集したり、テキストで座標や文字列などを指定して表示したりができないと、せっかくprocessingをやっていてもその本領を発揮できていないということになるかもしれません。
今回はpng、gif、txt、csvの順に読み込み方法を挙げていきたいと思います。
目次
その前に
ファイルの読み込みをしたいので当然、対象とするファイルが必要です。
対象とするファイルは、pdeファイルと同じところに置いたり、スケッチフォルダ内に新たに「データ」などとフォルダをつくってそこに入れておいたりすればOKです。
あるいは、対象とするファイルをコード編集画面にドラッグ・アンド・ドロップすることでも入れることができます。この場合はスケッチフォルダに「data」という名前のフォルダがつくられ、そこに入れられます。
URLで指定することもできます。
また、読み込むときにはファイルを指定しないといけません。
画像を自分で準備して行う際は、ファイル名のみで良い場合とどこにあるかも書く場合とがあります。
例えば「test.png」というファイルを読み込みたいとき…
「test.png」がpdeファイルの隣にある、あるいは「data」という名前のフォルダに入っているときは、ファイル名のみで良いです。
"text.png"
「test.png」のあるフォルダの名前が「data」以外であるとき(例えば「データ」)は、ファイルのある場所も指定します。
"データ/text.png"
対象とするファイルが入ったフォルダがさらに別のフォルダの中にあるなどという場合は、「/」で「~の中の」と指定していけば良いです。
例えば、「データ」フォルダの中の「画像」フォルダに入っているとすれば、
"データ/画像/test.png"
ネット上の画像を拾ってくるなどの場合は、保存しなくてもURLで指定できます。
例えばこのURLで指定すれば、木のフラクタルの記事から画像を拾ってきてくれます。
"https://cdn-ak.f.st-hatena.com/images/fotolife/t/taq2777/20211010/20211010042422.png"
もちろんこれは何らかの関数の引数で指定するものなので、これだけでは機能しません。
細かい方法はそれぞれで説明します。
pngの読み込み
pngを例にしていますが、画像ファイルなら同様に読み込めるかも。
画像専用の型(int、float、Stringなどの、その値が何であるかを指定するもの)「PImage」があり、それで指定した文字に「loadImage()」で画像を代入して、「image()」で描画する、という流れです。
PImage img; //型の宣言 void setup(){ size(500, 500); img = loadImage("test.png"); //画像の読み込み } void draw(){ image(img, 0, 0, 500, 500); //画像の描画 }
「image()」では引数が5つあり、それぞれ(画像, 位置のx座標, 位置のy座標, 画像の幅, 画像の高さ)となっています。
画像の座標は左上の座標で指定します。
画像の幅・高さは指定しなくても良く、その場合は読み込んだ画像の大きさとなります。
gifの読み込み
gifは画像ファイルのひとつなので、pngと同じ方法でも読み込めます。しかし動きはしません。
ここで登場するのがお馴染みのライブラリ「gifAnimation」。
import gifAnimation.*; //ライブラリの読み込み Gif gif; //Gifクラスのgifを作成 void setup(){ size(500, 500); gif = new Gif(this, "test.gif"); //ファイルの読み込み gif.play(); //gifを再生する } void draw(){ image(gif, 0, 0, 500, 500); //gifの表示 }
ちなみに「gif.play();」が無いと、pngと同じ方法で読み込んだときと同じ、つまり静止画で表示されます。
txtの読み込み
生成時と同様、2つの方法があります。
例として、以下のようなtxtファイルをつくって実行してみます。
a,b,c,d,e f,g,h,i,j
- loadStrings()
1つ目は「loadStrings()」を使う方法です。
この方法では文字列を配列に保存します。
String[] texts = loadStrings("test.txt"); //ファイルの読み込み for(int i = 0; i < texts.length; i ++){ //文字列の行の数だけ println(texts[i]); //i行目の文字列を表示する } exit(); //プログラムを終了する
- createReader()
2つ目は「createReader()」を使う方法です。
この方法では文字列を1行ずつ保存します。
BufferedReader reader; String line; void setup(){ reader = createReader("test.txt"); //読み取るファイルを選択 } void draw(){ try{ line = reader.readLine(); //1行読み取ってlineに保存 }catch(IOException e){ e.printStackTrace(); println("error"); } if(line == null){ //文字列が無くなったとき exit(); //プログラムを終了する }else{ //文字列があるとき println(line); //表示する } }
このコードはレファレンスにあるものをほとんどマネしたもので完全には理解できていませんので、ざっくりとですが説明します。
「BufferedReader reader」は1行ずつ読むときに必要らしく、"読み取り機"と捉えれば良いです。
「createReader()」で読み取り機に対象となるファイルを認識させ、「readLine()」で読み込んでいます。
「try{}catch(){}」はセットで使い、「try」以下のコードの実行結果で"例外"が生じたときに「catch」以下のコードが実行されるらしいです。
今回のコードでは、例外が出たときにそのときの文字列を「null」にするようになっています。
(この程度のファイルではほぼ関係ないと言ってもよさそうですが。)
「IOException」はその例外のひとつのようで、入出力で何か問題が起こったときに出るとか出ないとか。
「printStackTrace()」は例外が発生するまでのログのようなものらしいです。
実行するとどちらの例もtxtファイルと同じ文字列が表示されました。
便利さからいえば、今のところは圧倒的に「loadStrings()」を使った方が良さそうです。
ここからsplit()などで「,」で分ければ各文字を取り出すこともできますが、そのようなデータはcsvにした方が良いかもしれません。
csvの読み込み
テキストファイルのひとつではあるのでtxtと同じ方法でも読み込めます。
しかし、これではcsvの真価を発揮できません。
Excelで開けるぐらいですから「表」です。なので読み込みも表で行います。
表専用の型「Table」があるのでそれを使います。
例として、以下のようなcsvファイルをつくって実行してみます。
a,b,c,d,e f,g,h,i,j
読み込むコードは以下のようになります。
Table t; //型の宣言 t = loadTable("test.csv"); //ファイルの読み込み println(t.getString(0, 0)); //0行目の0列目の文字を表示 /* 実行結果 a */
「loadTable()」で読み込み、「getString(i, j)」でi行目のj列目の文字を取得しています。
今回の例ではi、jの値はそれぞれ0~1、0~4であり、配列と同様に、1からではなく0から始まります。
「String」の部分を「Int」や「Float」に変えれば値も読み取れます。
今回の例ではそれぞれ「0」、「NaN」が返されます。
まとめ
というわけで、ファイルの読み込み方についてまとめてみました。
これで大抵のファイルは読み込めるようになったのではないでしょうか。
それでは、また次回。