この記事で扱っていること
- 2Dピクチャで消しゴム機能を実装する方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
LabVIEWで画像ファイルや図形を表示する際に使用できる2Dピクチャには、基本的な図形である円や四角形等を簡単に描画できる関数が揃っているため、これらを組み合わせるだけで「ペイント」のようなことができます。
いくつかの機能を既に備えたサンプルもLabVIEWに付属しているので、これだけでもやりたいことができる、という場合もあるかと思います。
ただし、サンプルおよび関数自体に「消しゴム」の機能は実装されていません。
ないものは作るしかない、ということで、2Dピクチャに対する消しゴム機能を実装する方法を紹介します。
どんな結果になるか
ここでは、サンプルプログラム「ペン属性と画像サブセット」に消しゴム機能を追加するという場面を想定します。
(実際にはこのサンプル以外のプログラムでも使える方法となります。)

指定したペンの太さに応じて消しゴムで一度に消せる大きさが変わります。

プログラムの構造
プログラムのベースは、LabVIEWのメニューバーのヘルプから「サンプルを検索」で開くNIサンプルファインダにて見つかる「ペン属性と画像サブセット」を使用しています。

大部分のケースはサンプル通りなので、サンプルのまま編集しないケースについては紹介を省きます。
編集を加える必要があるのはこの中の一部です。

なお、上の図とサンプルプログラムを見比べると、最初のピクチャ定数の有無に気づくと思います。
今回のプログラムでは、「下絵」となるピクチャがある必要があり、例としてデフォルトのアイコンの絵を載せています。
これは別のサンプルプログラムから入手できます。

考え方は単純で、クリックされた場所もしくはドラッグされた場所に対して「下絵」の色(ピクセル値)を抜き出して今描画しているレイヤに置換してやるだけです。
ただし、「ペンの太さ」を太くすることで、一度に多くの領域の色抜き出しおよび置換をする必要があるので、そこは工夫が必要になります。
まずはピクチャのマウスダウンイベントに対して、以下のような修正を加えます。
erase_area.viというのは後から紹介するサブVIです。
なお、下の図のケースストラクチャの「5」は、動作を決定する列挙体の5番目の項目を「消しゴム」としていることに由来します。

続いてピクチャのマウス移動イベントに対しても以下のように編集を加えます。
またまた、erase_area.viが登場します。

次にピクチャのマウス境界内イベントです。
「消しゴム」を選択した際に、マウスカーソルをどのような表示にするかを決めます。
今回は「8」を指定していますが、別にここはどのような見た目でも構いません。

メインのVIの修正はこれで終わりで、あとは先ほどから数回出ているerase_area.viというサブVIの紹介です。
フロントパネルおよびコネクタペーンは以下のようにしています。

中身は以下のようにします。
ブロックダイアグラムの下の方にある二重のForループでは、ペン属性のクラスタの「幅」に応じて消しゴムで消す領域の大きさに合わせた(x,y)のペアを作成しています。
このペアにMouse Positionをx、yそれぞれに足し合わせることで、「消しゴムの大きさを考慮した、消す領域の座標」の二次元配列がxとyそれぞれで作成できます。
この情報を、右上にある二重Forループに渡して、original pictureの該当箇所の色でpictureの色を置換してやります。

注意点としては、この機能は下絵がないと意図したとおりに動かないことです。
例えば、サンプルプログラムのままだと「空のピクチャ」が下絵扱いになりますが、この場合サブVIのoriginal picture配列では要素を持つことができないため、右上のForループでは「無」から指標配列でデータを取り出すことになり、期待した動作になりません。
決まった色で塗りつぶしたい場合
場合によっては下絵ごと消したいこともあると思います。
消した後の色はどうするか、基本的には白になると思いますが、別に白一択である必要もないので、ユーザーが選べるようにしてみました。

なお、もし白を選ぶ際には、カラーパレットの右上の方にある白の領域を選ぶ必要があります。
(なぜだか、白を選んでも、黒で塗りつぶされてしまうようで、気を付けてください。)
メインVIに対して修正を加える部分としては以下のピクチャのマウスダウンイベントとなります。

サブVIの中身も一部変更します。

この方法はあくまで下絵ごと選んだ色で塗りつぶしているように上から色を重ねて見せているだけであって本当に塗りつぶす(つまり下絵の情報がなくなる)わけではないため、サンプルにある「クリア」のボタンを押すと下絵は復活するのでその点は注意してください。
本記事では2Dピクチャに対して消しゴム機能を実装する方法を紹介しました。
消すという感覚よりはむしろ値を置換する、上書きするという操作をしているだけなのですが、見た目上は消しゴム機能として使えるので、参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント