我的程序应该用我在boundaryFill4方法中指定的颜色(开头的黑色和白色)填充非常规形状。这是myImage.png的链接:https://dl.dropbox.com/u/41007907/myImage.png 我使用了一个非常简单的泛洪填充算法,但它不能以某种方式工作......这是完整的代码:
import java.awt.Color;
import java.awt.Container;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MyPolygon extends JFrame {
private JLabel my;
public MyPolygon() throws InterruptedException {
createMy();
}
private void createMy() throws InterruptedException {
Container contentPane = getContentPane();
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
contentPane.setSize(1000, 700);
my = new JLabel();
my.setIcon(new ImageIcon("myImage.png"));
my.setBounds(50, 50, 300, 300);
contentPane.add(my);
setSize(1000, 700);
setVisible(true);
setLocationRelativeTo(null);
int fill = 100;
boundaryFill4(100, 100, fill, 50);
}
// Flood Fill method
public void boundaryFill4(int x, int y, int fill, int boundary) {
int current;
current = getPixel(x, y);
if ((current >= boundary) && (current != fill)) {
setPixel(x, y, fill);
boundaryFill4(x + 1, y, fill, boundary);
boundaryFill4(x - 1, y, fill, boundary);
boundaryFill4(x, y + 1, fill, boundary);
boundaryFill4(x, y - 1, fill, boundary);
}
}
// Getting the color integer at specified point(x, y)
private int getPixel(int x, int y) {
Image img = ((ImageIcon) my.getIcon()).getImage();
BufferedImage buffered = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
buffered.getGraphics().drawImage(img, 0, 0, null);
Color c = new Color(buffered.getRGB(x, y));
int current = buffered.getRGB(x, y);
return current;
}
// Setting the color integer to a specified point(x, y)
private void setPixel(int x, int y, int fill) {
Image img = ((ImageIcon) my.getIcon()).getImage();
BufferedImage buffered = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
buffered.getGraphics().drawImage(img, 0, 0, null);
int red = fill;
int green = fill;
int blue = fill;
Color c = new Color(buffered.getRGB(x, y));
c = new Color(red, green, blue);
buffered.setRGB(x, y, c.getRGB());
}
// Main method
public static void main(String args[]) throws InterruptedException {
MyPolygon my = new MyPolygon();
my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
为什么我会收到StackOverflow错误?我该如何纠正它以便我的代码有效?
答案 0 :(得分:3)
您可以尝试将递归方法(boundaryFill4
调用自身)转换为非递归方法。这样JVM堆栈就不会溢出。
另一个选择是增加堆栈的大小 - 请参阅What is the maximum depth of the java call stack?
答案 1 :(得分:2)
StackOverflowException意味着你的递归对你的记忆来说太深或者没有结束。 尝试使用较小的图像。如果这不能解决问题,那么递归结束条件就会出现问题。 (setPixel()和getPixel真的改变了Image吗?写一个JUnitTest)
另外,你真的应该简化你的setPixel和getPixel方法。它们太复杂了。 对于您设置的每个Pixel或让您创建一个新的BufferedImage-Instance,然后在设置一个像素后进行处理。 您可以存储和重用BufferedImage。
答案 2 :(得分:1)
您应该调试boundaryFill4
方法:它是发生无限循环的地方。使用简单的案例来跟踪方法的反应。
此外,您应该避免在每次递归迭代时写入/读取图像。在开始时实例化表示图像的正确有效的数据结构,然后修改此数据结构,当算法结束时,将结果写为图像。