簡體   English   中英

為什么在使用Flood Fill算法時出現java.lang.StackOverflowError?

[英]Why do I get java.lang.StackOverflowError when using Flood Fill algorithm?

我的程序應該使用我在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錯誤? 我該如何糾正它以使我的代碼正常工作?

您可以嘗試將遞歸方法( boundaryFill4調用自身)轉換為非遞歸方法。 這樣,JVM堆棧不會溢出。

另一個選擇是增加堆棧的大小-請參閱java調用堆棧的最大深度是多少?

StackOverflowException意味着您的遞歸對於內存而言太深或沒有結束。 嘗試較小的圖像。 如果這不能解決問題,則遞歸結束條件有問題。 (setPixel()和getPixel確實會更改Image嗎?編寫一個JUnitTest

同樣,您確實應該簡化setPixel和getPixel方法。 它們太復雜了。 對於您設置或獲取的每個像素,都創建一個新的BufferedImage-Instance,然后在設置一個像素后對其進行處理。 您可以存儲和重用BufferedImage。

您應該調試您的boundaryFill4方法:這是發生無限循環的地方。 使用簡單的案例來跟蹤該方法的反應。

此外,您應避免在每次遞歸迭代時都寫入/讀取圖像。 在開始時實例化一個合適且有效的數據結構,以表示圖像,然后修改此數據結構,並在算法結束時將結果寫為圖像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM