📜  Java Applet |实现洪水填充算法

📅  最后修改于: 2021-04-24 03:59:05             🧑  作者: Mango

洪水填充算法是用指定的颜色替换某个封闭的或相似颜色的字段。在油漆和其他游戏(例如扫雷)中可以看到FloodFill算法的使用。

在本文中,通过使用FllodFill算法在Java Applet中将FloodFill用于指定颜色的连接区域。

可以使用两种方法:

  1. 递归方法(限制使用,因为它在更大的范围内崩溃)
  2. 使用队列(更可靠)

例子:

  1. 对于图片1:
    • 输出(充满在位置35、35处):
    • 输出(充满在位置1、1):
  2. 对于图片2:
    • 输出(充满在位置35、35处):
    • 输出(充满在位置1、1):
  3. 对于图片3:
    • 输出(充满在位置35、35处):
    • 输出(充满在位置1、1):

程序1:要使用递归在Java Applet中实现Floodfill算法:

注意:要运行该程序,请使用脱机IDE(例如Netbeans,Eclipse等)。请下载输入图像并将其与类文件一起放置。否则,程序可能会产生“无法读取输入文件”错误。

// Java Program to implement floodfill algorithm
// in Java Applet(using recursion)
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
  
public class floodfill extends JApplet {
  
    public void init()
    {
    }
  
    // paint function
    public void paint(Graphics g)
    {
        BufferedImage i = null;
        try {
            // Input the image to be used for FloodFill
            // The output is shown for 3 images
            // image1, image2 and image2
            i = ImageIO.read(new File("image1.jpg"));
  
            // floodfill with color red at point 35, 35
            // get color of image at 35, 35
            Color c = new Color(i.getRGB(35, 35));
            flood(i, g, 35, 35, c, Color.red);
  
            // draw the image after floodfill
            g.drawImage(i, 100, 100, this);
        }
        catch (Exception e) {
            JOptionPane.showMessageDialog(this, e.getMessage());
        }
  
        // draw the image after floodfill
        g.drawImage(i, 100, 100, this);
    }
  
    // function to floodfill the image
    public void flood(BufferedImage i,
                      Graphics g,
                      int x,
                      int y,
                      Color c,
                      Color c1)
    {
        if (x >= 1 && y >= 1
            && x < i.getWidth()
            && y < i.getHeight()) {
            // find the color at point x, y
            Color c2 = new Color(i.getRGB(x, y));
  
            // if there is no boundary (the color is almost
            // same as the color of the point where
            // floodfill is to be applied
            if (Math.abs(c2.getGreen() - c.getGreen()) < 30
                && Math.abs(c2.getRed() - c.getRed()) < 30
                && Math.abs(c2.getBlue() - c.getBlue()) < 30) {
                // change the color of the pixel of image
                i.setRGB(x, y, c1.getRGB());
  
                g.drawImage(i, 100, 100, this);
  
                // floodfill in all possible directions
                flood(i, g, x, y + 1, c, c1);
                flood(i, g, x + 1, y, c, c1);
                flood(i, g, x - 1, y, c, c1);
                flood(i, g, x, y - 1, c, c1);
            }
        }
    }
}

输出:

  • 对于图片1:
    输入:

    输出 :
  • 对于图片2:
    输入:

    输出 :
  • 对于图片3:
    输入:

    输出 :

    注意:如果使用递归方法在较大的区域(在坐标1、1)充满洪水,则递归算法可能会崩溃。

    例子:

    填充图像的较大部分输入: 输出: 说明:由于要覆盖的区域非常大,因此算法仅覆盖了一部分,之后程序崩溃了。

    程序2:要使用队列在Java Applet中实现Floodfill算法:

    注意:要运行该程序,请使用脱机IDE(例如Netbeans,Eclipse等)。请下载输入图像并将其与类文件一起放置。否则,程序可能会产生“无法读取输入文件”错误。

    // Java Program to implement floodfill algorithm
    // in Java Applet(using queue)
    import java.awt.*;
    import javax.swing.*;
    import java.awt.image.*;
    import java.io.*;
    import javax.imageio.ImageIO;
      
    public class floodfill extends JApplet {
      
        public void init()
        {
        }
      
        // paint function
        public void paint(Graphics g)
        {
            BufferedImage i = null;
            try {
                // Input the image to be used for FloodFill
                // The output is shown for 3 images
                // image1, image2 and image2
                i = ImageIO.read(new File("image1.jpg"));
      
                // floodfill with color red at point 1, 1
                // get color of image at 1, 1
                // if 35, 35 point is floodfilled it will floodfill
                // the smaller area
                Color c = new Color(i.getRGB(1, 1));
                flood(i, g, 1, 1, c, Color.red);
      
                // draw the image after floodfill
                g.drawImage(i, 100, 100, this);
            }
            catch (Exception e) {
                JOptionPane.showMessageDialog(this, e.getMessage());
            }
      
            // draw the image after floodfill
            g.drawImage(i, 100, 100, this);
        }
      
        // function to floodfill the image using queue
        public void flood(BufferedImage i,
                          Graphics g,
                          int x1,
                          int y1,
                          Color c,
                          Color c1)
        {
            // create a stack using array
            int stx[] = new int[100000];
            int sty[] = new int[100000], f, r, x, y;
      
            // create a front and rear
            f = r = 0;
      
            // initilize them
            stx[0] = x1;
            sty[0] = y1;
      
            // while front is greater than rear
            while (f >= r) {
                // pop element out
                x = stx[r];
                y = sty[r++];
                if (x >= 1 && y >= 1
                    && x < i.getWidth()
                    && y < i.getHeight()) {
                    // find the color at point x, y
                    Color c2 = new Color(i.getRGB(x, y));
      
                    // if there is no boundary (the color is almost
                    // same as the color of the point where
                    // floodfill is to be applied
      
                    if (Math.abs(c2.getGreen() - c.getGreen()) < 30
                        && Math.abs(c2.getRed() - c.getRed()) < 30
                        && Math.abs(c2.getBlue() - c.getBlue()) < 30) {
      
                        // change the color of the pixel of image
                        i.setRGB(x, y, c1.getRGB());
      
                        g.drawImage(i, 100, 100, this);
      
                        // floodfill in all possible directions
                        // store them in queue
                        stx[f] = x;
                        sty[f++] = y + 1;
                        stx[f] = x;
                        sty[f++] = y - 1;
                        stx[f] = x + 1;
                        sty[f++] = y;
                        stx[f] = x - 1;
                        sty[f++] = y;
                    }
                }
            }
        }
    }
    

    输出:

    • 对于图片1:
      输入:

      输出(充满在位置35、35处):

      输出(充满在位置1、1):

    • 对于图片2:
      输入:

      输出(充满在位置35、35处):

      输出(充满在位置1、1):

    • 对于图片3:
      输入:

      输出(充满在位置35、35处):

      输出(充满在位置1、1):