「初めてのProcessingコード」では、loadImageという関数を使ってURLを指定して画像を表示する、というコードを書いた。
実はloadImageはURLだけではなく、PC上にある画像を表示することも可能だ。
早速試してみよう。
新しいスケッチを作る
前回はネット上にあるイケメンの画像を表示するスケッチを”DisplayTesh01”と名付けて保存したが、今回は”DisplayTesh02”というスケッチを作る。
“ファイル–>新規”をクリックすると、新しいスケッチのウィンドウが開く。
このスケッチは仮の名前として日付とアルファベットを組み合わせた名前になっているので、今度は”スケッチ–>名前をつけて保存”として、”DisplayTesh02”という名前にする。
画像ファイルを追加する
これから表示しようとするファイルをスケッチに追加する。
“スケッチ–>ファイルを追加”を開いて、追加したいファイルを選ぶ。
(同じファイルで試したい方はこちらからダウンロードをどうぞ)
ファイルを追加したら、それを確認してみよう。
“スケッチ–>スケッチフォルダーを開く”とすると、Windowsではエクスプローラ、Macではファインダーが開いて、スケッチフォルダーが開く。
スケッチフォルダを開くと、”data”というサブフォルダができている。この”data”を開くとその中に、先程追加した画像が入っている。
追加した画像を表示する
先程追加した画像を表示するコードは下記の通り。
PImage image; // 変数 imageを宣言
void setup() {
size(640, 640); // ウィンドウサイズを640x640に指定
//ファイルから画像を読み込む
image = loadImage("data/adayinasia.png");
}
void draw() {
image(image, 0, 0); // “image”を表示する
}
前回のDisplayTesh01との違いは、4行目と6行目だけである。
先程追加した画像はサイズが640×640なので、4行目をそうなるように変更した。みなさんはここで追加した自分の画像のサイズを打ち込むこと。
その画像を読み込むのが6行目の処理だ。前回はURLで指定したが、今回は”data/ファイル名”となっている。これは、「相対パス」といって、スケッチフォルダからの相対的な場所で指定している。スケッチフォルダの”data”というサブフォルダの下に追加した画像ファイルが入っていたが、それを”data/画像ファイル名でしていしている。ここで”/”(スラッシュ)はサブフォルダーを表すもので、Windowsでは”¥”を使うが、Processingではスラッシュを使う。
これを実行すると窓が開き、追加した画像が表示される。
また、スケッチフォルダからの相対パスではなく、PC上の任意の場所にある画像を表示する場合は「絶対パス」を使う。絶対パスはWindowsでは”ドライブ名:/フォルダ名/…”と表す。ここでも”¥”ではなくスラッシュを使う。例えばCドライブ直下の”Temp”というフォルダにあるtesh.pngというファイルは絶対パスでは”C:/Temp/tesh.png”と表す。
参考までに、Windowsではユーザーのホームフォルダは”C:/ユーザ/(ユーザ名)”、Macでは”/Users/(ユーザ名)”、Linuxでは”/home/(ユーザ名)”と表す。
画像を保存する
ファイルから画像を読み取ることができたので、今度は画像をファイルに保存することにしよう。先程のコードの11行目に下記を追記する。
save(data/copied.jpg""); // 画像を保存する
画像を保存するための関数は”save”だ。引数には保存するときのパスを書く。
このスケッチを実行すると、dataフォルダの中に、新しく画像ファイルができている。
この例では、”png”という拡張子で読み込み、”jpg”という拡張子で保存しているが、この拡張子に合わせてPNGで読み込んだものをJpegに変換して保存できている。
ここで問題が。。。
save関数を使うことによって画像を保存することができるようになった。だが、ここでちょっと気になることがある。setup関数はプログラム実行の最初に一度だけ呼ばれるが、そのあとdraw関数は繰り返し呼ばれ続ける、ということを思い出していただきたい。
draw関数が呼ばれるたびに同じ画像が何度も何度も保存され続けるのは無駄なことだし、保存中にプログラムを止められるとファイルに書き込み中で中断してしまうこともあり、ファイルが壊れてしまう。
なので、draw関数の中でファイルを保存するのはあまりいい方法ではない。
ではどうすればよいか?
プログラム終了時に一度だけ呼ばれる関数
プログラム開始時に一度だけ呼ばれるsetup関数の逆で、プログラム終了時に一度だけ呼ばれる関数があれば、プログラム終了時に一度だけ画像を保存することになるのでそれが理想的だ。
Processingにはプログラム終了時に一度だけ呼ばれるdisposeという関数がある。このdisposeの中で画像を保存すれば良い。
先程の11行目のコードを一旦削除して、このコードの一番下に下記の3行を追加する。
void dispose() {
save(data/copied.jpg""); // 画像を保存する
}
まとめ
今回はPC上の画像ファイルを読み込む方法、また画像をファイルに書き込む方法を学習した。読み込み、書き込みの際にファイル名につけられる拡張子によって、自動的にファイルのフォーマットに合わせて処理し、必要であれば自動的にフォーマット変換もおこなっているということがわかった。