投稿者 tel | 2016年7月15日

1ドットのアウトラインを描く

1ドットのアウトラインを描画する方法を考えてみた。

outline_ss outline_ss02

図のように緑の部分と青の境界部分に1ドットの赤い線を描く。

  • 緑の部分を塗りつぶし処理で領域を取得。
  • 塗りつぶした領域を収縮させる。
  • 収縮した部分を任意の色で描画する。

塗りつぶし

同じ色の範囲を領域として取得する。
領域取得用に2値の画像と同じサイズのバッファを用意する。効率は良くないが今回は再帰的に塗りつぶす手法を使った。

// c: 塗りつぶす範囲の色
// data: 元の画像
// tmp: 塗りつぶし範囲のバッファ
// x, y: 開始座標
(function f(x, y) {
    if(x >= w || x < 0) return;
    if(y >= h || y < 0) return;
    if(data[y * w + x] === c && tmp[y * w + x] === 0) {
        tmp[y * w + x] = 1;
        f(x - 1, y);
        f(x + 1, y);
        f(x, y - 1);
        f(x, y + 1);
    }
})(x, y);

領域収縮(erosion)

収縮は対象の領域を1画素分小さくする処理。注目した画素の周りに違う色の画素があった場合にその画素をけずる。
4近傍で見るので上下左右の画素をチェックしている。

for(var i = 0; i &lt; h; i++) {
    for(var j = 0; j &lt; w; j++) {
        var k = i * w + j,
            p = tmp[k] === 1,
            b = false;
        if(i &gt; 0) b |= tmp[k - w] === 0;
        if(i &lt; h - 1) b |= tmp[k + w] === 0;
        if(j &gt; 0) b |= tmp[k - 1] === 0;
        if(j &lt; w - 1) b |= tmp[k + 1] === 0;
        if(p &amp;&amp; b) {
            data[i * w + j] = newColor;
        }
    }
}

削った部分がアウトラインになるので指定の色で塗っている。

結果

outline_ss

紫色の部分を指定して中央の領域のアウトラインを白で描く。

outline_ss2

 


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー

%d人のブロガーが「いいね」をつけました。