Java中的FloodFill

时间:2015-02-08 02:49:36

标签: java awt bufferedimage flood-fill

我正在尝试实现一个FloodFill版本,该版本在向上/向下方向上进行递归调用,但在左/右方向上使用迭代。但是,由于我缺乏图形编程经验,实施起来很痛苦。让我先写下我一直在做的事情,让你明白发生了什么:

首先,我在BufferedImage加载了我要将FloodFill应用到的测试图像:

m_objShape = ImageIO.read(FloodFillTest.class.getResourceAsStream("Untitled.png"));

canvas.drawImage(m_objShape, 100, 100, null);

图片看起来像这样:

enter image description here

在此之后,我从我创建的托盘中选择带填充颜色的颜色,然后使用MouseEvent检测图像被点击的位置。

现在,一切正常,直到我调用FloodFill,

我的first问题是除非我最小化并恢复Java Applet,否则不会应用颜色。

second问题是x方向循环未到达图像的末尾。即使我的循环被设置为停止,如果找到不同的像素。递归调用也是一种灾难,它不尊重图像的边界。这是我的代码:

private void DoFloodFill(int x, int y) {
    int startColor = GetPixel(x, y);

    int fillColor = m_objSelectedColor.getRGB();

    if(startColor == fillColor) return;

    FloodFill(x, y, m_objShape.getWidth(), m_objShape.getHeight(), fillColor, startColor);
}

private void FloodFill(int x, int y, int w, int h, int fillColor, int startColor) {

    if(x < 0 || y < 0 || x >= w || y >= h) return;

    if(GetPixel(x, y) != startColor) return;

    int xx = x;

    while(xx < w && GetPixel(xx, y) == startColor){
        SetPixel(xx - 100, y - 100 , fillColor);
        xx++;
    }

    int p = x - 1;

    while(p >= 0 && GetPixel(p, y) == startColor){
        SetPixel(p - 100  , y - 100, fillColor);
        p--;
    }

    FloodFill(x, y + 1, w, h, fillColor, startColor);
    FloodFill(x, y - 1, w, h, fillColor, startColor);
}

public void SetPixel(int x, int y, int nColor){
    m_objShape.setRGB(x, y, nColor);
}

public int GetPixel(int x, int y){
    return(m_objShape.getRGB(x, y));
}

图像应该是627Wx454H,当我在中间点击时,第一个循环在甚至达到第600个像素之前停止。 StartColor等于-1或-16777216 othertimes。但是,这些值与我点击的值不匹配。有人可以解释一下发生了什么吗?

由于

编辑举个例子,我在第一个while循环之后注释掉了代码。现在,这些是以下变量的值:

x:482

是的:289

w:627

h:454

xx:532

而且,图像看起来像这样。但是,该行应该到达图像的末尾。

enter image description here

1 个答案:

答案 0 :(得分:0)

最后,我犯了很多错误。但是,可以用这种方式解决它。然而,正如@ The111所说,它不是很安全,因为我很容易得到它。

private void DoFloodFill(int x, int y) {
    // TODO Auto-generated method stub

    int x_offset = x - 100;
    int y_offset = y - 100;

    int startColor = GetPixel(x, y);

    int fillColor = m_objSelectedColor.getRGB();

    if(startColor == fillColor) return;

    FloodFill(x_offset, y_offset, m_objShape.getWidth(), m_objShape.getHeight(), fillColor, startColor);
}

private void FloodFill(int x, int y, int w, int h, int fillColor, int startColor) {

    if(x < 0 || y < 0 || x >= w || y >= h) return;

    if(GetPixel(x, y) != startColor) return;

    int xx = x, left = 0, right = 0;

    while(xx < w && GetPixel(xx, y) == startColor){
        SetPixel(xx, y , fillColor);
        right = xx;
        xx++;
    }

    xx = x - 1;

    while(xx >= 0 && GetPixel(xx, y) == startColor){
        SetPixel(xx, y, fillColor);
        left = xx;
        xx--;
    }

    while(xx < right){
        FloodFill(xx, y - 1, w, h, fillColor, startColor);
        FloodFill(xx, y + 1, w, h, fillColor, startColor);
        xx++;
    }

}