FloodFill算法产生StackOvlerflowError

时间:2015-02-27 01:59:55

标签: java bufferedimage stack-overflow flood-fill

我有一个包含图像的Java程序,我正在尝试使用以下函数(@ canvas是{BufferedImage,使用填充算法来补充封闭区域内每个黑色像素的白色像素。 {1}}):

public void floodFill(Point2i start, int target, int grep){
    if(start.x < 0 || start.x >= width || start.y < 0 || start.y >= height)return;
    if(canvas.getRGB(start.x, start.y) != target)return;
    canvas.setRGB(start.x, start.y, grep);
    floodFill(new Point2i(start.x+1, start.y), target, grep);
    floodFill(new Point2i(start.x-1, start.y), target, grep);
    floodFill(new Point2i(start.x, start.y+1), target, grep);
    floodFill(new Point2i(start.x, start.y-1), target, grep);
}

问题是,我在第三行得到一个java.lang.StackOverflowError ....我认为必须有一个更好的方法来做这个不会导致这个错误,不是吗?我正在运行具有相当大量RAM(2 GB)的JVM,那么如何为可用的BufferedImage编写泛洪填充函数?

2 个答案:

答案 0 :(得分:2)

如果target equals grep,您的计划将始终返回上一点。

例如:

  • 从点(0,0) - &gt;转到点(1,0)......
  • 从点(1,0) - &gt;转到点(2,0),然后转到点(0,0)

因此,您应该使用布尔数组或类似方法检查所有访问点。请查看Depth first search以获取更多信息。

您可以考虑从递归到迭代方法切换,这对内存更友好,有关详情,请参阅Breadth first search

增加堆栈大小也有帮助,因为k_g已在他/她的回答中指出。

答案 1 :(得分:1)

增加内存不会增加堆栈大小。

尝试将-Xss64m添加到您的VM参数中。这会增加你的堆栈大小。

或者,您可以通过创建Stack<Point2i>并添加初始点来创建内部堆栈。然后,您将执行while循环,该循环在堆栈为空时结束,以调用您的函数并从堆栈中删除该点。该函数将堆栈作为参数(或者,它可以是类字段)并将点添加到堆栈而不是调用自身。