1

我的程序应该用我在 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 错误?我怎样才能纠正它,以便我的代码工作?

4

3 回答 3

3

您可以尝试将递归方法(boundaryFill4调用自身)转换为非递归方法。这样 JVM 堆栈就不会溢出。

另一种选择是增加堆栈的大小 - 请参阅Java 调用堆栈的最大深度是多少?

于 2013-04-09T08:32:08.993 回答
2

StackOverflowException 意味着您的递归对于您的记忆来说太深或没有结束。尝试使用较小的图像。当这不能解决问题时,您的递归结束条件有问题。(setPixel() 和 getPixel 真的会改变图像吗?写一个JUnitTest

此外,你真的应该简化你的 setPixel 和 getPixel 方法。它们太复杂了。对于您设置或获取的每个像素,您都创建一个新的 BufferedImage-Instance,然后在设置一个像素后将其处理掉。您可以存储和重用 BufferedImage。

于 2013-04-09T08:32:57.987 回答
1

您应该调试您的boundaryFill4方法:这是发生无限循环的地方。使用简单的案例来跟踪方法的反应。

此外,您应该避免在递归的每次迭代中写入/读取图像。在开始时实例化一个适当且高效的表示图像的数据结构,然后修改该数据结构,当算法结束时,将结果写入图像。

于 2013-04-09T08:32:06.507 回答