java - 协调越界!在Java中,洪水填充

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

谁知道为什么会发生这种情况? :)谢谢!

最佳答案

未正确检查 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。假设刚刚使用 x = 30y = 99 调用了 floodfill()。 if 语句检查完毕,因此您可以看到接下来的两行,现在您正在调用 floodFill(30, 100, [color])。该调用将尝试将 floodFill() 中的第一行运行为 int rgb = img.getRGB(30, 100),现在 y超出范围,因为您的 y 像素最多只能达到 99。

floodFill() 的其余部分中,类似的情况发生在其他图像边缘

关于java - 协调越界!在Java中,洪水填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21475107/

相关文章:

java - 如何使这个输出成为 boolean 值?

java - 用于分割字符串的正则表达式

java - java打印数组越界

java - 获取 JScrollPane 内的鼠标坐标

path - 点到路径的最短距离

java - 从 Java 中的 Enum 类型参数获取信息

java - "cannot find symbol"试图关闭 I/O 对象时

rust - 为实现特定类型的 trait 的泛型类型实现 trait

c++ - 我应该在我的代码中使用 std::vector::at()

ios - Storyboard xcode 上的坐标系令人困惑?