我写了一个经典的队列洪水填充:
public static void floodFill(int y, int x, byte originalvalue, byte newvalue, byte[][] arr) {
Deque queue = new ArrayDeque();
queue.add(new int[]{y, x});
while (!queue.isEmpty()) {
int[] t = (int[]) queue.poll();
y = t[0];
x = t[1];
if (arr[y][x] == originalvalue) {
arr[y][x] = newvalue;
for (int i = 0; i < 8; i++) {
if (x + dx[i] < arr[0].length && y + dy[i] < arr.length && x + dx[i] > -1 && y + dy[i] > -1 && arr[y + dy[i]][x + dx[i]] == originalvalue) {
queue.add(new int[]{y + dy[i], x + dx[i]});
}
}
}
}
}
现在我想写扫描线Flood Fill,这要快得多。我无法找到任何伪代码,我也不理解this code。
你能帮我优化补洪或写入扫描线吗?
我将这个泛洪填充称为一个字节数组,其大小为1000-2000×1000-2000(不一定是正方形),对于较大区域一次,然后对于较小区域则为1000到1,000,000次。
答案 0 :(得分:1)
这是一种改进的泛洪填充算法。
,不是填充像素,而是填充其邻居,而是填充像素的整个水平“运行”,然后填充其邻居。递归如下:
至Fill(X0, X1, Y, Old, New)
:
# Precondition: the segment [X0 X1]/Y has the old color and can't be lengthened
查找具有旧颜色和[X0' X1']
Y-1
中的所有已关联的投放Fill(X0', X1', Y-1, Old, New)
查找具有旧颜色和[X0' X1']
Y+1
中的所有已关联的投放Fill(X0', X1', Y+1, Old, New)
要查找新行中的所有已连接的距离,请从X0
开始,只要您在旧像素上向左移动,或者只要您在非旧像素上向右移动(停在X1
);你有X0'
。然后在旧像素上继续向右;你有X1'
。只要X0'
位于[X0 X1]
。
一些实现细节取决于您选择的4/8连接规则。