漫水填充及Photoshop中魔術棒選擇工具的實現

2022-02-05 22:04:22 字數 1358 閱讀 6248

今天寫程式中有乙個地方用到了漫水填充(floodfill)。所謂漫水填充,簡單來說,如下圖中左圖,白布上有一塊紅色的斑點,在這個紅色的斑點上點一下,就自動選中了和該點相連的紅色的區域,接著將該區域替換成指定的顏色,如下圖中右圖所示。

gdi中有乙個函式 extfloodfill ,可以用於漫水填充。函式原型是:

bool extfloodfill(hdc hdc,int nxstart,int nystart,colorref crcolor,uint fufilltype)

在c#中使用這個函式並不好用,這裡有乙個例子

。照貓畫虎的寫了一遍,結果返回的結果是false——填充失敗。

對win32這些東西看著就煩,也沒心思去看到底**出錯了,乾脆自己寫乙個 floodfill 演算法得了。

演算法很簡單:

(1)將最初的點作為種子點壓入棧中;

(2)彈出乙個種子點,把它塗成目標顏色;

(3)對於種子點來說,和它相鄰的有4個畫素,判斷這4個畫素中的顏色是否是背景色,如果是,則作為新的種子點入棧;

(4)迴圈至棧空。

實現起來也很簡單,一共只需要22行**,比用dllimport去呼叫extfloodfill**量還少:

void floodfill(imagergb24 img, point location, rgb24 backcolor, rgb24 fillcolor)

if (p.x < ww && img[p.y, p.x + 1] == backcolor)

if (p.y > 0 && img[p.y - 1, p.x] == backcolor)

if (p.y < hh && img[p.y + 1, p.x] == backcolor)

}

}

有這個演算法為基礎,類似photoshop的魔術棒選擇工具就很容易實現了。漫水填充(floodfill)是查詢和種子點聯通的顏色相同的點,魔術棒選擇工具則是查詢和種子點聯通的顏色相近的點,將和初始種子點顏色相近的點壓進棧作為新種子。

在photoshop cs5中新引進了快速選擇工具,這個工具看起來很神奇,它背後的演算法也研究了有些年了,就是摳圖技術,有興趣的可以去研究,這裡有一篇很好的綜述文章:《

image and video matting: a survey

》。

漫水填充及Photoshop中魔術棒選擇工具的實現

今天寫程式中有乙個地方用到了漫水填充 floodfill 所謂漫水填充,簡單來說,如下圖中左圖,白布上有一塊紅色的斑點,在這個紅色的斑點上點一下,就自動選中了和該點相連的紅色的區域,接著將該區域替換成指定的顏色,如下圖中右圖所示。gdi中有乙個函式 extfloodfill 可以用於漫水填充。函式原...

漫水填充演算法

所謂漫水填充演算法,是給定乙個聯通域內的乙個點,以此為起點找到這個聯通域的其餘所有點並將其填充為指定顏色的一種演算法。之所以稱之為漫水填充,是因為這種演算法就是模擬了漲水的過程,從一點開始,水流慢慢加大,直到漫過了全部區域。這個演算法的詳細介紹可以參考下面的鏈結。這個演算法在我們尋找一片指定區域時非...

漫水填充演算法

漫水填充演算法是填充演算法中最通用的演算法。所謂漫水填充 演算法,是給定乙個聯通域內的乙個點,以此為起點找到這個聯通域的其餘所有點並將其填充為指定顏色的一種演算法。之所以稱之為漫水填充,是因為這種演算法就是模擬了漲水的過程,從一點開始,水流慢慢加大,直到漫過了全部區域。該填充演算法的原型如下所示 v...