我正在编写一个实现 Flood Fill 4 算法的应用程序。只要边框很厚,它就可以完美地工作。该算法在边框内填充某种颜色。我试图使边框变薄,但在这种情况下,像素能够超出边框,并且程序崩溃了。
洪水填充算法在“厚边界”区域(即直角三角形)内表现出色。然而,该算法在其他四个区域内不起作用,因为边界很薄,即发生泄漏。除了让其他边框变厚之外,还有什么方法可以使用吗?
这是完整的代码,它只是一个类:
import java.awt.Color;
import java.awt.Container;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class MyPolygon extends JFrame {
private JLabel my;
private BufferedImage buffered;
public MyPolygon() throws InterruptedException {
createMy();
}
private void createMy() throws InterruptedException {
Container contentPane = getContentPane();
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
contentPane.setSize(1200, 900);
my = new JLabel();
my.setIcon(new ImageIcon("myImage.png"));
my.setBounds(10,200, 1000, 800);
contentPane.add(my);
setSize(1200, 900);
setVisible(true);
setLocationRelativeTo(null);
Image img = ((ImageIcon) my.getIcon()).getImage();
buffered = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
buffered.getGraphics().drawImage(img, 0, 0, null);
int fill = 100;
boundaryFill4(200, 215, fill, 50);
my.setIcon(new ImageIcon(buffered));
}
// Flood Fill method
public void boundaryFill4(int x, int y, int fill, int boundary) {
Color c = new Color(buffered.getRGB(x, y));
int current = c.getRed();
System.out.println(x + " " + y + " | " + current);
if ((current > boundary) && (current != fill)) {
int red = fill;
int green = fill;
int blue = fill;
c = new Color(red, green, blue);
buffered.setRGB(x, y, c.getRGB());
boundaryFill4(x + 1, y, fill, boundary);
boundaryFill4(x - 1, y, fill, boundary);
boundaryFill4(x, y + 1, fill, boundary);
boundaryFill4(x, y - 1, fill, boundary);
}
}
// Main method
public static void main(String args[]) throws InterruptedException {
MyPolygon my = new MyPolygon();
my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
最佳答案
您的 if
需要一些工作,并且除了颜色之外,您的递归没有结束条件。
1
函数boundaryFill4
需要查找x和y是小(图片的上边缘或左边缘)还是大(下边缘或上边缘)。它看起来像这样:
if (x < 0 || x > 200 || y < 0 || y > 200) {
return;
}
2
如果仔细观察图像,您会发现边框线的边缘(尤其是细时)使用褪色像素来防止线条看起来过于锯齿状。这是一种平滑技术。
一个调试技巧是在 boundaryFill4
函数的顶部添加一个短时间延迟,以便您可以看到正在发生的过程。它应该向您显示填充物正在逃逸的位置,您可以查看炸毁的那个位置以获得更多线索。
当前测试会查找其中红色含量超过 50 级但与填充颜色不同的红色的像素。
中间的白色可能具有全部三个 RGB 级别的完整值。
边框的所有三种 RGB 颜色的像素似乎都接近 0,但平滑技术使其在某些像素中放置更高的 RGB 值以隐藏锯齿。请务必检查边框较薄时实际的颜色级别。也许线条的中心像素比您想象的更亮。
填充颜色是一种深灰色。
- 代码将根据“红色大于 50”的规则查找白色。
- 代码将避免使用“not RED == fill”规则重做已经填充的内容
- 它在平滑边界上的作用尚不清楚。我的猜测是,有一个地方,边框的较亮部分比 50(红色)更亮
这里有一些想法:
- 更改规则以在与填充颜色进行比较时查看所有三种颜色,而不仅仅是红色。 (红色==填充,绿色==填充和蓝色==填充)这可能没有帮助。
- 也许您可以传递起始点的颜色并用它进行比较,而不是仅仅填充比 50 更亮的所有内容。要么寻找精确的颜色匹配,要么寻找足够接近的匹配,其中该点在 10 以内传递的原始颜色。
- 如果这不起作用,请利用延迟来查看其逃逸位置的独特之处。
关于java - 使用Flood Fill 4算法时如何克服 "thin border"问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15954305/