协调出界!在Java中,洪水填充

时间:2014-01-31 08:02:35

标签: java bounds coordinate flood-fill

我试图找出为什么我得到“坐标超出界限!”当试图实施洪水填充。这是一个黑白图像,当有白色时,在洪水填充时不会发生任何事情,并且它不是那么好。所有的黑色区域都会充满红色,有些区域会变红,直到我收到坐标超出范围的错误消息。这是源代码:

 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);
            }
        });
    }
}      

任何可能知道为什么会这样的人? :)谢谢!

1 个答案:

答案 0 :(得分:4)

未正确检查floodFill()调用参数的界限。

看看以下几行:

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

假设您的图片高100像素。像素在每个轴上编号为0-99。说floodfill()只是使用x = 30y = 99来调用。 if语句检出,所以你到达接下来的两行,现在你正在调用floodFill(30, 100, [color])。该调用会尝试将floodFill()中的第一行作为int rgb = img.getRGB(30, 100)运行,现在y超出范围,因为您的y像素最多只能达到99.

floodFill()的其余部分中的其他图像边缘也会发生类似的事情。