我有一个包含图像的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编写泛洪填充函数?
答案 0 :(得分:2)
如果target equals grep
,您的计划将始终返回上一点。
例如:
因此,您应该使用布尔数组或类似方法检查所有访问点。请查看Depth first search以获取更多信息。
您可以考虑从递归到迭代方法切换,这对内存更友好,有关详情,请参阅Breadth first search。
增加堆栈大小也有帮助,因为k_g已在他/她的回答中指出。
答案 1 :(得分:1)
增加内存不会增加堆栈大小。
尝试将-Xss64m
添加到您的VM参数中。这会增加你的堆栈大小。
或者,您可以通过创建Stack<Point2i>
并添加初始点来创建内部堆栈。然后,您将执行while
循环,该循环在堆栈为空时结束,以调用您的函数并从堆栈中删除该点。该函数将堆栈作为参数(或者,它可以是类字段)并将点添加到堆栈而不是调用自身。