优化自定义泛洪填充算法(Java)

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

标签: java graphics flood-fill

我根本没有任何类型的泛洪填充算法的经验。但我给了我最好的一击。首先,我会在用户点击洋红色的任何地方填充一个像素,然后经过一个循环,在每个品红色像素的顶部,左侧,底部和右侧绘制一个像素。这将花费8秒钟来完成特别大面积的填充。所以我添加了另一个循环,它向上,向下,向左和向右绘制了直的洋红色线条。这减少了时间。我让计算机绘制了更多的线条......左上,左上,左上,左下......等等。现在它已经下降到1和1之间。 2秒。我还能做些什么来减少完成填充所需的时间?

  for(Point p:shiftDownPoints)
  {
     //down
     for(int y = p.y+1; y<SCREEN_DIM.height; y++)
     {
        if(capture.getRGB(p.x,y)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x,y,Color.MAGENTA.getRGB());
     }
     //up
     for(int y = p.y-1; y>0; y--)
     {
        if(capture.getRGB(p.x,y)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x,y,Color.MAGENTA.getRGB());
     }
     //right
     for(int x = p.x+1; x<SCREEN_DIM.width; x++)
     {
        if(capture.getRGB(x,p.y)==Color.BLACK.getRGB())break;
        else capture.setRGB(x,p.y,Color.MAGENTA.getRGB());
     }
     //left
     for(int x = p.x-1; x>0; x--)
     {
        if(capture.getRGB(x,p.y)==Color.BLACK.getRGB())break;
        else capture.setRGB(x,p.y,Color.MAGENTA.getRGB());
     }
     //down-right
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x+i,p.y+i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x+i,p.y+i,Color.MAGENTA.getRGB());
     }
     //down-left
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x-i,p.y+i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x-i,p.y+i,Color.MAGENTA.getRGB());
     }
     //up-left
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x-i,p.y-i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x-i,p.y-i,Color.MAGENTA.getRGB());
     }
     //up-right
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x+i,p.y-i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x+i,p.y-i,Color.MAGENTA.getRGB());
     }
     //up-up-left
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x-i,p.y-i*2)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x-i,p.y-i*2,Color.MAGENTA.getRGB());
     }
     //up-left-left
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x-i*2,p.y-i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x-i*2,p.y-i,Color.MAGENTA.getRGB());
     }
     //down-left-left
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x-i*2,p.y+i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x-i*2,p.y+i,Color.MAGENTA.getRGB());
     }
     //down-down-left
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x-i,p.y+i*2)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x-i,p.y+i*2,Color.MAGENTA.getRGB());
     }
     //down-down-right
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x+i,p.y+i*2)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x+i,p.y+i*2,Color.MAGENTA.getRGB());
     }
     //down-right-right
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x+i*2,p.y+i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x+i*2,p.y+i,Color.MAGENTA.getRGB());
     }
     //up-right-right
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x+i*2,p.y-i)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x+i*2,p.y-i,Color.MAGENTA.getRGB());
     }
     //up-up-right
     for(int i = 1; i<Math.min(SCREEN_DIM.width,SCREEN_DIM.height); i++)
     {
        if(capture.getRGB(p.x+i,p.y-i*2)==Color.BLACK.getRGB())break;
        else capture.setRGB(p.x+i,p.y-i*2,Color.MAGENTA.getRGB());
     }
  }

  while(pixelsDrawn)
  {
     pixelsDrawn=false;
     for(int x = 0; x<SCREEN_DIM.width; x++)
        for(int y = 0; y<SCREEN_DIM.height; y++)
        {
           if(capture.getRGB(x,y)==Color.MAGENTA.getRGB())
           {
              if(capture.getRGB(x-1,y)!=Color.MAGENTA.getRGB()
              &&capture.getRGB(x-1,y)!=Color.BLACK.getRGB())
              {
                 capture.setRGB(x-1,y,Color.MAGENTA.getRGB());
                 pixelsDrawn = true;
              }
              if(capture.getRGB(x+1,y)!=Color.MAGENTA.getRGB()
              &&capture.getRGB(x+1,y)!=Color.BLACK.getRGB())
              {
                 capture.setRGB(x+1,y,Color.MAGENTA.getRGB());
                 pixelsDrawn = true;
              }
              if(capture.getRGB(x,y-1)!=Color.MAGENTA.getRGB()
              &&capture.getRGB(x,y-1)!=Color.BLACK.getRGB())
              {
                 capture.setRGB(x,y-1,Color.MAGENTA.getRGB());
                 pixelsDrawn = true;
              }
              if(capture.getRGB(x,y+1)!=Color.MAGENTA.getRGB()
              &&capture.getRGB(x,y+1)!=Color.BLACK.getRGB())
              {
                 capture.setRGB(x,y+1,Color.MAGENTA.getRGB());
                 pixelsDrawn = true;
              }
           }
        }
  }

2 个答案:

答案 0 :(得分:0)

感谢immibis的建议,我把洪水填满了半秒钟。在这个新代码中,我让计算机沿着轮廓边缘创建一个多边形,然后只使用图形中的fillPolygon。

  for(Point p:iterablePoints)
  {
     int dir = 2; //0:right, 1:down, 2:left, 3:up
     int xPos = p.x;
     int yPos = 0;
     Polygon poly = new Polygon();
     for(int y = p.y; y>0; y--)
     {
        if(capture.getRGB(p.x,y-1)==Color.BLACK.getRGB())
        {
           yPos = y;
           break;
        }
     }
     Vector<Point> tempRecord = new Vector<Point>();
     boolean run = true;
     while(run)
     {               
        if(dir==0&&capture.getRGB(xPos+1,yPos)==Color.BLACK.getRGB())dir--;
        else if(dir==1&&capture.getRGB(xPos,yPos+1)==Color.BLACK.getRGB())dir--;
        else if(dir==2&&capture.getRGB(xPos-1,yPos)==Color.BLACK.getRGB())dir--;
        else if(dir==3&&capture.getRGB(xPos,yPos-1)==Color.BLACK.getRGB())dir--;
        else 
        {
           if(dir==0)xPos++;
           if(dir==1)yPos++;
           if(dir==2)xPos--;
           if(dir==3)yPos--;

           dir++;

           tempRecord.add(new Point(xPos,yPos));
           if(tempRecord.size()>1)if(tempRecord.get(0)==tempRecord.get(1))tempRecord.remove(tempRecord.firstElement());
           else startPoint = tempRecord.get(0);
           if(startPoint!=null)if(startPoint.x==xPos&&startPoint.y==yPos) run=false;
           poly.addPoint(xPos,yPos);capture.setRGB(xPos,yPos,Color.MAGENTA.getRGB());
        }
        if(dir==4)dir=0;
        if(dir==-1)dir=3;
     }
     Graphics cg = capture.getGraphics();
     cg.setColor(Color.MAGENTA);
     cg.fillPolygon(poly);
     cg.dispose();
  }

答案 1 :(得分:-1)

讨论泛洪填充算法可能需要一个完整的课程。我认为你应该咨询This Link,因为它解释了一切,如何逐像素地与算法一起绘制(有效)。希望这会有所帮助。