この記事で扱っていること
- 標準関数だけで画像専用のファイルダイアログを作る方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
プログラムの中で、ファイルを選択するといった操作を行うことはよくあります。
対象となるファイルはテキストファイルである場合もあれば、中には画像ファイルを指定してその画像に対して処理を行うといった場合も考えられます。
ここで問題になるのが、画像ファイルを選ぶときの選び方で、LabVIEWに標準関数として存在しているファイルダイアログのExpress VIでは、Windowsのファイルエクスプローラが開くことになります。
表示メニューを変えて大アイコン等にすれば画像ファイルに対して画像は確認できるものの、画像を検索する目的がある場合には使い勝手が少し悪いです。
LabVIEWのアドオンソフトであるVision関係のソフトがインストールされている場合には画像を表示できる表示器が付いたファイルダイアログが使用できますが、有償ソフトなので使える人も限られると思います。
そこで、本記事では画像専用のファイルダイアログを自作してみました。
こんな機能があったらいいなと思ったので、画像の任意倍率での拡大表示機能も付けています。
どんな結果になるか
フロントパネルにはファイルのダイアログらしくファイルパスの表示器や上の階層に戻るためのボタン、あらかじめ指定したパスに戻るホームボタン、選択を決定あるいは中止するボタンの他に、ファイルのリストを表示するリストボックスと、画像を表示するピクチャボックス表示器、画像のファイルパスとズームの係数を指定する数値制御器、ズーム倍率を1に戻すボタンがあります。
プログラムを実行するとあらかじめ指定したホームディレクトリに進みそのディレクトリ内のフォルダやファイルの一覧が表示されます。
(下の画像では全て拡張子がついていますが、フォルダがリストボックスに表示される場合には拡張子が付かないことによって区別できます)
画像ファイルに対してダブルクリックすると画像をピクチャ上に表示させることができ、ズーム係数を変更すると画像の拡大(1より小さい値を指定した場合には縮小)が行えます。
なお、このフロントパネルには実際には「スタートディレクトリ」のファイルパス制御器と、もう一つの「画像ファイルパス」のファイルパス表示器が画面外にあります。
これは、このviがサブviとして他のviから呼び出されることを想定した作りとしているためで、viのプロパティを設定してフロントパネルを表示させるようにしておけば、まさにファイルダイアログとして使用でき、選んだ画像ファイルを呼び出し側のviで使うことができるようにしています。
プログラムの構造
以前に別の記事でファイルダイアログをカスタマイズする方法を紹介していました。
その記事でもそうでしたが、この手のプログラムにはステートマシンが便利です。
全体像は以下の図の通りです。
それぞれの操作に対してステートを設けるのでステートの数は少し多めですが、その分一つ一つでやることはシンプルになります。
クラスタにはこのviで使用するデータの一式が入っていて、各ステートでこのクラスタの中身にアクセスして処理を進めていきます。
では各ステートの中身を紹介します。
まずはinitステートです。
フロントパネルの表示枠外にあるスタートディレクトリに値が入っていない場合にはあらかじめ決めておいたホームディレクトリ(下の図の場合にはユーザデスクトップ)を基準にするようにしています。
もし、このviをサブviとして他のviから呼び出す場合にその呼び出し側のviからスタートディレクトリに何か特定のファイルパスを選択している場合にはそのディレクトリをホームディレクトリとします。
このパスの情報をcurrent directoryとしておき、それ以外にズーム係数の値であるzoom factorも初期化として1をいれておきます。
なお、このinitステートは最初以外にも使用するのですが、2回目以降はズーム係数を初期化する必要がないので、初めて呼び出す場合にしかこの操作をしていません。
その他リストボックスの初期化や2Dピクチャの大きさを定義しています。
次に進むのはupdate listステートです。
ここでは、current directoryのパス情報をフォルダをリスト関数に渡してフォルダとファイルの配列をリストボックスの項目名プロパティに渡しています。
このとき、フォルダの配列とファイルの配列を配列連結追加で合体していますが、上に来ているのがフォルダの配列となるようにしています。
(なので、下の図でフォルダをリストから配列連結追加へ入力している部分では配線がクロスしています)
次にeventステートです。
文字通り、イベントストラクチャを用いて各ユーザーの操作に対してイベント検知し次のステートを決定します。
ほとんどのイベントは大した処理をしていませんが、リストボックスのダブルクリックイベントだけはステートの分岐があります。
current directoryの中身とダブルクリックした行の情報から新たなパスを作成し、そのパスがディレクトリになっているかを判定、Trueならselect folderにFalseならselect fileステートに進むようにしています。
これ以外のイベントの中身は以下の通りです。
select folderステートではtarget pathをcurrent directoryに変更し、この次にupdate listに進んでリストボックスの表示を更新するようにしています。
select fileの場合には、そのファイルパスのファイルの拡張子を取得してその種類によって画像情報を取得し、2Dピクチャに表示しています。
なお、select fileとして選ばれたファイルパスが画像ファイルではない場合でもこのselect fileステートが実行されますが、ピクチャに何も表示されなくなるだけなので、そもそも画像ファイルであるかどうかの場合分けは今回は行っていません。
go to homeステートでは、initステートに戻ります。
ホームディレクトリに戻るという処理を行うだけですね。
なので、別にこのgo to homeというステートを作らなくても、ホームボタンが押されたらinitに直接進む、という形でも問題ありません。
もしinitの前に何か特定の処理を追加するかもしれない時に備えて分けています。
zoomステートではzoom factorの値を2Dピクチャのズーム係数プロパティに入れています。
この程度の処理であればイベントストラクチャの中で処理させてもいいとは思いますが、ズームに伴って何か別の処理を行うことを想定してこのステートを用意しました。
go to parent folderステートでは、current directoryの情報からパスをストリップしてその情報を再びcurrent directoryに入れています。
cancelステートでは文字通りファイルの選択をキャンセルするためにWhileループを止めています。
このとき画像ファイルパスには空のパス定数を配線しています。
最後にfinish selectステートです。
target pathとして選択したパスを画像ファイルパスに配線しています。
使い勝手を良くするための工夫
基本的な操作は上で紹介したプログラムで事足りると思います。
ただ、さらに修正を加えることでより使い勝手がよくなるので修正例を紹介していきます。
まずは、「ファイルとして表示される対象が画像ファイルだけにする」ための修正で、具体的にはupdate listのステートでフォルダをリスト関数のパターン入力を使用して表示させるファイルの種類を制限するというものです。
フォルダをリストの関数のパターン入力では拡張子の指定ができるのですが、一つの拡張子パターンしか一度に指定できないようなので、配列とForループを使用して複数のパターンをまとめて処理しています。
他の修正としては、「ファイルパスに手入力でパスを入力してそのパスに一気にアクセスする」ことも考えられます。
この場合、ファイルパスの部分は制御器になっている必要があるため、今まで表示器にしていた部分はもう制御器にしてしまい、ファイルパスの値変更イベントを追加するようにして対応するようにします。
本記事では標準関数だけで画像専用のファイルダイアログを作る方法を紹介しました。
標準関数だけでも画像に対して様々な処理を行うプログラムはこのブログでこれまでに多く紹介してきましたが、それらと合わせて使用する場合などに参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント