算法,洪水填充(深度优先搜索)

时间:2011-11-03 13:22:01

标签: java

我正在使用Java 我正在开发一个绘图程序,“Paint Can”工具正在使用Flood Fill算法,但它太贵了。

以下是代码:

private int[] dx = { -1, 0, 1, 0 };
private int[] dy = { 0, 1, 0, -1 };

public void floodFill(int x, int y, Color target_color, Color replacement_color) {
    Stack<Integer[]> stack = new Stack<Integer[]>();
    if (imageBuffer.getRGB(x, y) == replacement_color.getRGB())
         return;
    stack.push(new Integer[] { x, y });
    while (!stack.isEmpty()) {
        Integer[] aux = stack.peek();
        imageBuffer.setRGB(aux[0], aux[1], replacement_color.getRGB());
        stack.pop();
        for (int i = 0; i < 4; i++) {
            if (imageBuffer.getRGB(aux[0] + dx[i], aux[1] + dy[i]) == target_color.getRGB())
                stack.push(new Integer[] { aux[0] + dx[i], aux[1] + dy[i] });
        }

    }
}

有人可以帮助我提高效率吗?

需要(对于1020x700像素图像)执行大约1200ms。

4 个答案:

答案 0 :(得分:1)

使用队列算法的基本思路,你可以阅读here(+示例)。

您可以找到其他优化和实现,但我发现了这个Queue-Linear Flood Fill。你应该自己完成这项工作。

答案 1 :(得分:1)

一个快速简单(可能很小)的改进就是用ArrayDeque替换Stack。

这将允许您指定初始容量并使您的代码更新。当floodFill区域包含许多像素时,需要扩展多次向下扩展的Vector。这很浪费 - 但并不是那么昂贵

答案 2 :(得分:0)

大约一年前,我曾试图实施一次大量填充算法。我首先尝试了自己的解决方案,当他们的表现不够时,我上网并找到了this implementation

QuickFill(实际算法从页面的中间开始)算法运行良好。它将在不到半秒的时间内填满我的机器人里程碑的屏幕(480x854)。使用更新的硬件(甚至桌面硬件),它可能会比这更快。当然你必须把它移植到Java,但它不应该太难,特别是如果我能做到的话!

答案 3 :(得分:0)

我会说你有很多内存分配正在进行中。您为每个像素分配了一个新的Integer[]。我可能会使用两堆基元(比如trove4j中的数组列表)来处理xy,或者至少替换{{1与Integer[]

如果这还不够,也许scanline算法会有所帮助。