Question

I am trying to find out why I get "Coordinate out of bounds!" when trying to implement the flood fill. It's a black and white image, when there is white nothing should happen when flood filling, and it doesn't so that is good. All black areas is gonna be flood filled with red and some areas become red until I get the error message that the coordinates are out of bounds. Here is the source code:

 public class FloodFiller extends JPanel implements MouseListener {

    private BufferedImage img;

    public void turnBlacknWhite() {
        int x, y;
        int w = img.getWidth();
        int h = img.getHeight();
        // first compute the mean intensity
        int totintensity = 0;
        for (y = 0; y < h; y++) {
            for (x = 0; x < w; x++) {
                int rgb = img.getRGB(x, y);
                totintensity += (rgb >> 16) & 0xFF + (rgb >> 8) & 0xFF + rgb
                        & 0xFF;
            }
        }
        int meanintensity = totintensity / (w * h);
        for (y = 0; y < h; y++) {
            for (x = 0; x < w; x++) {
                int rgb = img.getRGB(x, y);
                int intensity = (rgb >> 16) & 0xFF + (rgb >> 8) & 0xFF + rgb
                        & 0xFF;
                if (intensity < meanintensity) { // it's darker than mean
                                                    // intensity
                    img.setRGB(x, y, 0); // turn black
                } else { // it's lighter
                    img.setRGB(x, y, 0xFFFFFF); // turn white
                }
            }
        }
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
        floodFill(e.getX(), e.getY(), 0xFF0000);
        this.repaint();
    }

    /**
     * Fill the black area including and around (x,y) with color. If (x,y) is
     * not black, do nothing.
     */
    public void floodFill(int x, int y, int color) {
        // TODO!
        int rgb = img.getRGB(x, y);
        int black = Color.black.getRGB();
        if (rgb == black) {

            if (x < img.getWidth() && y < img.getHeight() && x > 0 && y > 0) {
                img.setRGB(x, y, color);
                floodFill(x, y + 1, color);
            }

            if (x < img.getWidth() && y < img.getHeight() && x > 0 && y > 0) {
                img.setRGB(x, y, color);
                floodFill(x, y - 1, color);
            }
            if (x < img.getWidth() && y < img.getHeight() && x > 0 && y > 0) {
                img.setRGB(x, y, color);
                floodFill(x + 1, y, color);
            }
            if (x < img.getWidth() && y < img.getHeight() && x > 0 && y > 0) {
                img.setRGB(x, y, color);
                floodFill(x - 1, y, color);

            }

        }
    }

    // public void isValid (int width, int height) {
    // int coordinate = 0;
    // int width = img.getWidth();
    // int height = img.getHeight();
    // if (width && height => coordinate) {
    //
    // }
    // }

    public FloodFiller(String fileName) {
        URL imgUrl = getClass().getClassLoader().getResource(fileName);
        if (imgUrl == null) {
            System.err.println("Couldn't find file: " + fileName);
        } else {
            try {
                img = ImageIO.read(imgUrl);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        turnBlacknWhite();
        setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
        this.addMouseListener(this);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground(Color.WHITE);
        g.drawImage(img, 0, 0, null);
    }

    public static void main(String[] args) {
        final String fileName = args[0];
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Flood Filler");
                frame.setContentPane(new FloodFiller(fileName));
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}      

Anyone who might know why this happens? :) Thanks!

No correct solution

OTHER TIPS

The bounds on the parameters to the calls to floodFill() are not properly checked.

Look at these lines:

if (x < img.getWidth() && y < img.getHeight() && x > 0 && y > 0) {
    img.setRGB(x, y, color);
    floodFill(x, y + 1, color);
}

Say your image is 100 pixels tall and wide. The pixels are numbered 0-99 on each axis. Say floodfill() was just called with x = 30, y = 99. The if statement checks out, so you get to the next two lines, and now you are calling floodFill(30, 100, [color]). That call will try to run the first line in floodFill() as int rgb = img.getRGB(30, 100), and now y is out of bounds because your y-pixels only go up to 99.

Similar things happen on other image edges in the rest of floodFill().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top