delaunay

2016.11.22

描画系の表現でよく見かけるドロネー三角形です。
三角形描画の部分に関しては、こちらを参考にさせていただいています。
ただ三角形を描くのみだと少し味気ないかと思い、今回は、画像をベースに三角形を描くことにチャレンジしました。
また、せっかく画像をベースにするのだからいろいろな画像でスライドショーのようにできないかと考え、今回は3枚の画像をループで切り替えるようにしました。

このページの上部に掲載されているサンプルはシンプルなグラデーションの画像をベースにしていますが、写真や絵をベースにする場合は、どれくらい元の素材の姿・印象を崩さないまま分割できるかがキモになってくると思います。そのためには画像の加工を行い、輪郭線を検出した上で、三角形のポイントとなる点を打っていく必要があります。
いくつかのステップを踏むことで、元の素材の印象を残したまま、ドロネー三角形を描くことができます。
輪郭線検出の過程をわかりやすくするため、この文章内では下記画像を使用した際のサンプル画像も掲載しています。

s1

Delaunayクラスを定義

まずは1枚の画像をドロネー三角形分割させるDelaunayクラスを定義します。
冒頭に書いたように、3枚の画像をループさせるために、最終的にはDelaunayクラスのインスタンスを3つ作成します。
それぞれのインスタンスが各々見えないcanvasを保持しており、最終的に1枚のcanvasに描画するという形にしています。

画像加工

画像内にはランダムな点も配置するのですが、それだけだと、いざ三角形分割した際に元画像とかけ離れたものになってしまうため、画像加工を行って輪郭線を検出し、その輪郭線に沿った座標にも点を配置していきます。

1.コントラストの強いハッキリとした画像を作成

最初に、画像の明るさとコントラストを調整し、パキっとした画像を作成します。

 

この処理を行うと、画像はこのようにクッキリします。

s2

2.白黒画像から輪郭線を抽出

次は画像を白黒に変換することで、輪郭線の抽出を行います。
imageDataで色を取得し、ラプラシアンフィルタを2回かけることで、明確な白黒の画像を作成します。
そして画像内の白い箇所(輪郭線部分)の座標を保持します。

  この処理を行うと、画像はこのようになります。 s3  

三角形作成のための点を配置

保持した輪郭線座標の中から、ランダムで点を抽出します。

 

実際に輪郭線に沿った座標に点を配置すると、このようになります。(わかりやすくするため、ランダムで選ばれた座標に赤い点を描画しています)

s4

三角形の描画

完全にランダムな座標と、輪郭線に沿った座標を抽出することができたので、この2種類の点に時間差で三角形を描画していきます。
途中で描画をストップできるよう、setTimeoutのタイマーを配列で保持しておきます。

 

 

Delaunayクラスの全文はこちらです。

[delaunay.js]

包括するクラスの定義

最後に、Delaunayクラスのインスタンスを3つ作成するBgクラスを定義します。
3枚の画像が読み込まれてから三角形の描画がスタートするようにします。

[bg.js]

まとめ

あまりにも重くなることは避けたいため、今回は頂点数を少なめに設定しましたが、頂点数を多めに設定すると

s5

これくらいまで画像に沿った形で分割することができました。
何か一発画像をジェネレートするようなコンテンツであれば、これくらいの頂点数で挑むのも良いかなと思います。

また、IEで閲覧すると、画像が切り替わる際の輪郭線抽出作業時に画面がフリーズしてしまいます。for文で大量の計算を行うことがマズいようです。
今回はそのままにしていますが、実際に案件で使用する場合は、IE用のフォールバックを実装する必要がありそうです。