画像のなかの同じ色でつながっている部分をぬりつぶす。簡単にできるかと思ったら意外と難儀していまいました。

どんなプログラム?

マウスでクリックされたらその部分と同じ色でつながっている部分を塗りつぶします。

コンストラクタのなかで画像ファイルのパスを指定し読み込みます。

そのイメージをピクチャーボックスに表示させます。

マウスがクリックされたらその場所の色を調べて、これを赤で塗りつぶします。やりたいことはこれだけです。

問題はFillColorメソッドをどう書くかです。

再帰呼び出しで楽勝?

クリックされた座標をBitmap.GetPixelメソッドで調べてBitmap.SetPixelメソッドで色を変える。隣の色を調べて同じ色であればそこも色を変える。再帰呼び出しでいいのではないか?

はじめは安易に考えて以下のようなコードをかきました。

oldColorとnewColorが異なることをチェックしていますが、これはBitmap.GetPixelメソッドとoldColorが同じであれば処理をおこなうようにしているからです。oldColorとnewColorが同じであれば色を入れ替えてからも条件式が真を返すため、永久に処理が終わらないということになります。

サイズが大きい場合は再帰呼び出しは不適?

DameFillColorメソッドは画像サイズが小さければ問題なくできます。縦横100ピクセル程度であればなんとかできますが、それ以上大きくなるとスタックオーバーフローの例外が発生してしまいます。再帰の場合、呼び出し回数が極端に多いとうまく動いてくれません。

ではどうすればいいのか? 調べてみた結果、まず横1列だけ入れ替える色があるかどうか調べるという方法です。そしてその上下のピクセルを調べます。これをバッファに保存してそのピクセルがある横1列を調べて・・・を繰り替えす方法です。

この方法であれば画像サイズが大きく塗りつぶしの対象が入り組んだ形をしても対応できます。