【问题标题】:Coordinate out of bounds! In Java, flood fill坐标出界!在Java中,洪水填充
【发布时间】:2014-01-31 08:02:34
【问题描述】:

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

 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 / - 1floodFill 中的边界检查不正确
  • 对不起,我缺乏知识,但我不明白为什么它们不正确? y+1 下降一个像素,y-1 上升一个像素,x+1 向右,x-1 向左 - 你建议我如何解决?谢谢
  • 查看双陆棋答案。

标签: java bounds coordinate flood-fill


【解决方案1】:

没有正确检查对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() 其余部分的其他图像边缘也会发生类似的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2019-08-22
    相关资源
    最近更新 更多