1枚の画像について複数のリンクが設定されたものをクリッカブルマップといいます。そこで画像を読み込ませてクリックして領域を選択してリンク先を設定したらコピペするだけでクリッカブルマップをつくることができるアプリケーションをつくります。

クリッカブルマップの構造

生成されるコードは以下のようなものになります。shapeを=”rect”や”circle”にすることもできますが、今回は”polygon”(多角形)だけにします。

それから実験で使うイメージはここからダウンロードしました。

四国地方 地図 イラストイラスト – No: 2554054/無料イラストなら「イラストAC」

これがダウンロードした画像です。

四国の各県をクリックすると県庁のホームページに飛ぶようなものをつくります。

まずユーザーコントロールをつくり、ここにPictureBoxをはりつけます。

ユーザーコントロールにAutoScrollを設定して、PictureBoxのSizeModeプロパティをPictureBoxSizeMode.AutoSizeにすれば大きな画像であっても自動的にスクロールバーがつきます。あとはクリックされた場所を記憶できるようにしておけばクリッカブルマップになるHTMLコードを生成できそうです。

それからフォームはこんな感じになります。左側に貼り付けているのが上で作成したユーザーコントロール(クラス名はUserControlImage)です。

UserControlImageクラス

まずクリックされた座標をリストのなかに格納して多角形を描画するためのクラスをつくります。

Polygonクラス

コンストラクタには多角形を描画するための座標とリンク先のurlを渡します。あとはGetPointsメソッドで座標のリストのコピーを返し、GetTagメソッドで多角形の座標をHTMLに変換した文字列(<area href=”url.html” shape=”polygon” coords=”x1,y1 x2,y2 x3,y3 …”>)を返します。

UserControlImageクラスの機能

次にユーザーコントロールですが、以下の処理をおこないます。

ファイルをドラッグアンドドロップしたら画像ファイルであれば読み込んでPictureBoxに表示させる
画像が読み込まれた状態でクリックされたら座標を格納する
親フォームで[確定]ボタンがクリックされたらクリックされた座標で多角形が構成されているならPolygonをリストに格納する
親フォームで[HTMLタグを生成]がクリックされたらクリッカブルマップに対応したHTMLタグを出力する

やりたい処理は以上となります。

UserControlImageクラスの初期化

最初にコンストラクタを示します。

多角形を囲むPenを生成する

確定した多角形を囲むPenを生成する処理を示します。これは最初に1回だけやればよいのでコンストラクタの中で実行することにして、うっかり2回実行するようなことになってもMyPensのなかに要素がある場合はなにもしません。

ファイルがドラッグされているときの処理

次にドラッグされているときの処理を示します。ドラッグされているものが本当にファイルなのか、ファイルである場合、画像ファイルなのかを調べて適切なDragEventArgs.Effectを設定しなければなりません。

ファイルであるかどうかはDragEventArgs.Data.GetDataPresent(DataFormats.FileDrop)がtrueかどうかで調べられます。ファイルである場合はImage.FromFileメソッドにファイルパスを渡し例外が発生しなければ画像ファイルであると判断します。

ファイルのドロップされたときの処理

ファイルがドロップされたらそこがPictureBoxであってもユーザーコントロールであっても、ユーザーコントロールでOnDragDropメソッドが呼び出されます。この場合は画像ファイルのパスをフィールド変数に格納するとともにPictureBoxにイメージを表示させます。

すでに別のファイルが読み込まれていた場合はデータをリセットします。

PictureBoxがクリックされたときと再描画の処理

PictureBoxがクリックされたときの処理を示します。

クリックされたらその座標を調べてフィールド変数Pointsのなかに格納します。そしてPictureBox.Invalidateメソッドを実行します。

PictureBox.Invalidateメソッドを実行されたらPointsに座標が格納されている場合、それが1つだけだったら点を描画し(実際には幅高さ1の矩形)、複数の場合は順番に直線で結びます。またすでに確定している多角形が存在するのであれば、別の色で多角形を描画します。

多角形を確定させる処理

親フォームで[確定]が選択されたら格納されている座標が3以上である場合は多角形が形成されています。この場合は最初にPointsに格納された座標と最後に格納された座標をつないで多角形をつくり、これを確定します。そしてそれをPolygonsに格納し、Pointsは次の多角形を設定できるようにクリアします。処理が正常におこなわれた場合はtrueを返し、多角形が確定できない場合はfalseを返します。

結果を返すための処理

親フォームで[HTMLタグを生成]がクリックされたらクリッカブルマップに対応したHTMLタグを出力します。ユーザーコントロール側でやることはクリッカブルマップに対応したHTMLタグの文字列を返すだけです。

データをクリアする処理

Clearメソッドは現在確定している多角形はそのままで、現在Pointsに格納されている座標だけをクリアします。AllClearメソッドは現在確定している多角形もクリアするとともにPictureBoxに格納されているImageもクリアします。

仕上げ 親フォームにおける処理

あとは親フォームでボタンがクリックされたときの処理を定義するだけです。

[確定]ボタンがクリックされたら多角形を確定する処理をおこないます。リンク先が設定されていなかったり、座標が3点以上指定されていないため多角形を確定させることができない場合はエラーメッセージを表示します。

[クリア]、[全クリア]がクリックされたらデータをクリアする処理をおこないます。

クリッカブルマップをレスポンシブ対応させるには

[HTMLタグを生成]ボタンがクリックされたらHTMLタグを取得します。ただレスポンシブ対応にしたい場合はそのようなコードを取得しなければなりません。そこでチェックボックスにチェックが付いている場合はレスポンシブ対応のコードも追加します。

取得されたHTMLタグはRichTextBoxに表示されますが、ボタンをクリックしたらクリップボードにコピーされるようにしてしまえば便利かもしれません。