10/12/2008

Processing FileChooser2

以前「Processing FileChooser/ファイル選択画面の表示」でJava Swingを用いましたが、Processing 146以降からselectInput()によって、ファイル選択画面を通して任意の場所にあるファイルを読み込むことが簡単にできるようになりました。
以下は、「f」キーを押すとselectInput()で、ファイル選択画面を表示し、コンピュータの任意の場所にある画像を表示するサンプルです。表示された画像は、ドラッグすることで位置を変えられるようにしてあります。

//画像用インスタンス用意
PImage img;

//現在選択中のファイルパスの変数
String currentPath=null;
//画像配置座標の変数
int x,y;
//画像配置座標とクリック座標の差分の変数
int dx,dy;

void setup(){
  //画面サイズ設定
  size(600,400);
}

void draw(){
  //背景描画(黒)
  background(0);
  //現在選択中のファイルパスが空ではないとき
  if(currentPath!=null){
    //画像描画
    image(img,x,y);
  }
}

//クリックしたら
void mousePressed(){
  //画像配置座標とクリック座標の差分を求めておく
  dx=x-mouseX;
  dy=y-mouseY;
}

//ドラッグ中
void mouseDragged(){
  //マウス座標に差分座標を加えた値を画像配置座標とする
  x=mouseX+dx;
  y=mouseY+dy;
}

//キーを押した場合
void keyPressed(){
  //「f」キーなら
  if(key=='f'){
    //ファイル選択画面を表示し選択したファイルパス取得
    String loadPath = selectInput();
    //ファイルパスが空の場合
    if (loadPath == null) {
      //「ファイルが選ばれてない」メッセージを出力
      println("No file was selected...");
      //ファイルパスを前回のファイルパスにする
      loadPath=currentPath;
    } 
    else {//ファイルパスが選択された場合
      //ファイルパスのドット以降の文字列を取得(拡張子名を取得)
      String ext = loadPath.substring(loadPath.indexOf('.') + 1);
      //拡張子が「jpg」または「png」なら
      if(ext.equals("jpg") || ext.equals("png")){
        //選択ファイルパスの画像を取り込み
        img = loadImage(loadPath);
        //現在選択中のファイルパスを更新
        currentPath=loadPath;
        //現在選択中のファイルパスを出力
        println(currentPath);
      }else{//拡張子が「jpg」または「png」ではないとき
        //「画像ファイルではない」と出力
        println("Not image file.");
      }      
    }
  }
}


ファイル選択画面上で選択したファイルのパスを取得したら、substring()によってパスの文字列末尾に含まれる拡張子を調べます。その際、indexOf()を使うことで、パスの文字列に含まれる「.」を手掛かりに、パスの文字列末尾の拡張子を抜き出します(indexOf()は、括弧内に入れた文字が文字列中の何番目にあるかを教えてくれます)。
今回は、拡張子が「jpg」か「png」であれば、loadImage()で画像を取り込み、次回のためにファイルパスを記憶させておきます。それ以外の拡張子の場合は、"Not image file."だけを出力します。

selectInput()以外に、フォルダを選択するためのselectFolder()や、保存先を指定するselectOutput()も加えられています。

----------------------------------
以下は頂いたコメントに対するサンプルです。
import java.awt.*;

void setup() {
  size(200,200);
}

void draw(){  
}

void fileSelected(File selection) {
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
  } else {
    println("User selected " + selection.getAbsolutePath());
  }
}

void mousePressed(){
  FileDialog fd = new FileDialog(new Frame(),"Choose a file");
  fd.setDirectory("/Users/username/Desktop");//ここのディレクトリを任意に変えてください。
  fd.setVisible(true);
  if(fd.getFile()==null){
    println("Canceled");
  }else{
    println("FILE NAME:"+fd.getFile());
    println("DIRECTORY:"+fd.getDirectory());
  }
}

5 件のコメント:

  1. wombatと申します.
    selectInput()ですが,JAVAのswingを用いる場合に可能なように,ある特定のディレクトリから開くような処理はどのようにすればできるのかお教えいただくとありがたいです.あるいは不可能なのでしょうか?よろしくお願いします.

    返信削除
  2. 追記しておきました(ページさ最下部)。
    サンプルでは、クリックするとダイアログ画面が開き選択したファイル名とディレクトリが出力されます。
    fd.setDirectory("/Users/username/Desktop");
    ここに任意のディレクトリを入れてください。このままのコピペではデフォルトのディレクトリになってしまうでしょう。
    いちおうMac向けですが、Winなら"c:¥¥temp"などといれればいいと思います。

    返信削除
  3. 突然の書き込み失礼します。
    processingを勉強し始めたばかりのものです。

    selectinput()を使いかくてそちらのコードを参考にさせていただきましたが、
    PApplet is not applicable...をエラーが出ます。

    どのようにすれば使えるようになるのでしょうか?

    大変お手数ですが御教授下さい。

    返信削除
  4. 本稿のサンプルはProcessing1.5用なので、2.0からはselectInput()の()内にpromptとcallbackを入れないといけないようです。
    selectInput()のページのサンプルにあるように(以下)、

    void setup() {
    selectInput("Select a file to process:", "fileSelected");
    }

    void fileSelected(File selection) {
    if (selection == null) {
    println("Window was closed or the user hit cancel.");
    } else {
    println("User selected " + selection.getAbsolutePath());
    }
    }

    こんな感じで、使うといいです。
    追記したサンプルでは、あえてselectInput()を使わず、java.awtでやってます。
    selectInput()をつかうのであれば、上記サンプルを参考にしてみてください。

    返信削除
  5. 早速の御回答ありがとうございます。
    今後ともサンプルを参考にさせていただきます。

    返信削除