填入 Java
FloodFill in Java
我正在尝试实现一个 FloodFill
版本,该版本在 up/down 方向进行递归调用,但在 left/right 方向使用迭代。但是,由于我缺乏图形编程经验,实施起来很痛苦。让我先写下我一直在做的事情,以便您了解发生了什么:
首先,我加载了一个 BufferedImage
和我想要应用 FloodFill 的测试图像:
m_objShape = ImageIO.read(FloodFillTest.class.getResourceAsStream("Untitled.png"));
canvas.drawImage(m_objShape, 100, 100, null);
图像,看起来像这样:
在此之后,我 select 使用我创建的调色板中的填充颜色,并使用 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。但是,这些值与我单击的值不匹配。有人可以向我解释发生了什么吗?
谢谢
Edit 例如,我在第一个 while 循环后注释掉了代码。现在,这些是以下变量的值:
x: 482
y: 289
w: 627
小时:454
xx: 532
而且,图像看起来像这样。但是,该行应该到达图像的末尾。
最后,我错了很多。但是,可以这样解决。但是,正如@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++;
}
}
我正在尝试实现一个 FloodFill
版本,该版本在 up/down 方向进行递归调用,但在 left/right 方向使用迭代。但是,由于我缺乏图形编程经验,实施起来很痛苦。让我先写下我一直在做的事情,以便您了解发生了什么:
首先,我加载了一个 BufferedImage
和我想要应用 FloodFill 的测试图像:
m_objShape = ImageIO.read(FloodFillTest.class.getResourceAsStream("Untitled.png"));
canvas.drawImage(m_objShape, 100, 100, null);
图像,看起来像这样:
在此之后,我 select 使用我创建的调色板中的填充颜色,并使用 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。但是,这些值与我单击的值不匹配。有人可以向我解释发生了什么吗?
谢谢
Edit 例如,我在第一个 while 循环后注释掉了代码。现在,这些是以下变量的值:
x: 482
y: 289
w: 627
小时:454
xx: 532
而且,图像看起来像这样。但是,该行应该到达图像的末尾。
最后,我错了很多。但是,可以这样解决。但是,正如@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++;
}
}