首页 > 解决方案 > 使用洪水填充算法时出现 StackOverflowError

问题描述

我正在尝试实现洪水填充算法,使用特定颜色填充闭合形状。我认为我的代码已经完成,但我不知道为什么“StackOverflowError”会上升!

我越来越多地寻找解决方案,但没有找到完美的答案。

public void paintComponent(Graphics g){
    indecies.clear();

    float x1 = 20;
    float y1 = 20;
    float x2 = 350;
    float y2 = 20;
    /* put the points of first line in ArraList */
    for(int i = (int) x1; i < x2 ; i++){
        index = (int) (i + y1 * img.getWidth());
        list.add(index);
    }
    /***************************************************/
     x1 = 350;
     y1 = 20;
     x2 = 100;
     y2 = 100;
    /* put the points of second line in ArraList */
    for(int i = (int) y1; i <= y2 ; i++){
        index = (int) (x1 * img.getWidth());
        list.add(index);
    }
    /***************************************************/
    x1 = 100;
    y1 = 100;
    x2 = 20;
    y2 = 100;
    /* put the points of the third line in ArraList */
    for(int i = (int) x2; i < x1 ; i++){
        index = (int) (i + y1 * img.getWidth());
        list.add(index);
    }
    /*****************************************************/
    x1 = 20;
    y1 = 100;
    x2 = 20;
    y2 = 20;
    /* put the points of the forth line in ArraList */
    for(int i = (int) y2; i < y1 ; i++){
        index = (int) (x1 * img.getWidth());
        list.add(index);
    }        
    /**************************************************/

    /* Get each pixel from ArrayList of indecies then print into data raster of image */
    for (Integer integer : indecies) {
        pixels[integer] = Color.yellow.getRGB();
    }

    /* Flood fill recursive algorithm */
    /* border color is yellow */
    /* green is the new colow must be filled inside the shape */
    fill(50, 50, Color.yellow.getRGB(), Color.green.getRGB());
    g.drawImage(img, 0, 0, this);
}

这里是填充方法!!

public  void fill(int x, int y, int borderColor, int newColor){
       if(x >= 0 && x < width && y >= 0 && y < height){
            int index = x + y * width;
            if(pixels[index] != borderColor && pixels[index] != newColor){
                pixels[index] = newColor;
                fill(x, y - 1, borderColor, newColor);
                fill(x, y + 1, borderColor, newColor);
                fill(x + 1, y, borderColor, newColor);
                fill(x - 1, y, borderColor, newColor);
            }
        }
   }

异常详情..

java.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowErrorjava.lang.StackOverflowError


    at java.nio.Buffer.limit(Buffer.java:274)
        at java.nio.Buffer.<init>(Buffer.java:201)
        at java.nio.CharBuffer.<init>(CharBuffer.java:281)
        at java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:70)
        at java.nio.CharBuffer.wrap(CharBuffer.java:373)
        at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:265)
        at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
        at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
        at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
        at java.io.PrintStream.write(PrintStream.java:526)
        at java.io.PrintStream.print(PrintStream.java:669)
        at java.io.PrintStream.println(PrintStream.java:823)
        at java.lang.Throwable$WrappedPrintStream.println(Throwable.java:748)
        at java.lang.Throwable.printStackTrace(Throwable.java:655)
        at java.lang.Throwable.printStackTrace(Throwable.java:643)
        at java.lang.Throwable.printStackTrace(Throwable.java:634)
        at FillColorAlgorithm.fill(FillColorAlgorithm.java:170)
        at FillColorAlgorithm.fill(FillColorAlgorithm.java:162)
    ......... etc

标签: java

解决方案


public void floodFill(int x, int y, int borderColor, int fillColor, int imgWidth, int imgHeight){

    Queue<java.awt.Point> nodesList = new LinkedList<>();

    if(borderColor == fillColor) return;
    if(x >= 0 && x < imgWidth && y >= 0 && y < imgHeight){
        int index = x + y * imgWidth;
        if(pixels[index] == fillColor) return;
        nodesList.add(new java.awt.Point(x, y));
    }

    while(!nodesList.isEmpty()) {

        java.awt.Point currentNode = nodesList.element();
        int index = currentNode.x + currentNode.y * imgWidth;
        if(pixels[index] != fillColor){
            java.awt.Point westNode = currentNode;
            java.awt.Point eastNode = currentNode;

            westNode = MoveWest(westNode, borderColor);
            eastNode = MoveEast(eastNode, borderColor);

            for (int j = westNode.x + 1; j < eastNode.x; j++) {

                index = j + currentNode.y * imgWidth;
                pixels[index] = fillColor;

                java.awt.Point northNode = new java.awt.Point(j, currentNode.y - 1);
                java.awt.Point southNode = new java.awt.Point(j, currentNode.y + 1);

                index = northNode.x + northNode.y * imgWidth;
                if(northNode.y >= 0 && pixels[index] != fillColor && pixels[index] != borderColor) nodesList.add(northNode);

                index = southNode.x + southNode.y * imgWidth;
                if(southNode.y < imgHeight && pixels[index] != fillColor && pixels[index] != borderColor) nodesList.add(southNode);
            }
        }

        nodesList.remove();           
    }
}

java.awt.Point MoveWest(java.awt.Point w, int borderColor){
    int index;
    do{
        --w.x;
        index = w.x + w.y * width;
    }
    while(w.x >= 0 && pixels[index] != borderColor);

    return new java.awt.Point(w.x, w.y);
}

java.awt.Point MoveEast(java.awt.Point e, int borderColor){
    int index;
    do{
        ++e.x;
        index = e.x + e.y * width;
    }
    while( e.x < width && pixels[index] != borderColor);
    return new java.awt.Point(e.x, e.y);
}

推荐阅读