Flood fill

From Wikipedia, the free encyclopedia

Flood fill, also called seed fill, is an algorithm that determines the area connected to a given node in a multi-dimensional array. It is used in the "bucket" fill tool of paint programs to determine which parts of a bitmap to fill with color, and in puzzle games such as Minesweeper, Puyo Puyo, Lumines, and Magical Drop for determining which pieces are cleared.

recursive flood-fill with 4 directions

The flood fill algorithm takes three parameters: a start node, a target color, and a replacement color. The algorithm looks for all nodes in the array which are connected to the start node by a path of the target color, and changes them to the replacement color. There are many ways in which the flood-fill algorithm can be structured, but they all make use of a queue or stack data structure, explicitly or implicitly. One implicitly stack-based (recursive) flood-fill implementation (for a two-dimensional array) goes as follows:

Flood-fill (node, target-color, replacement-color):
 1. If the color of node is not equal to target-color, return.
 2. Set the color of node to replacement-color.
 3. Perform Flood-fill (one step to the west of node, target-color, replacement-color).
    Perform Flood-fill (one step to the east of node, target-color, replacement-color).
    Perform Flood-fill (one step to the north of node, target-color, replacement-color).
    Perform Flood-fill (one step to the south of node, target-color, replacement-color).
 4. Return.
recursive flood-fill with 8 directions

Though easy to understand, this implementation is impractical in languages and environments where stack space is severely constrained (e.g. Java applets).

An explicitly queue-based implementation might resemble the following:

Flood-fill (node, target-color, replacement-color):
 1. Set Q to the empty queue.
 2. If the color of node is not equal to target-color, return.
 3. Add node to the end of Q.
 4. For each element n of Q:
 5.  Set the color of n to replacement-color.
 6.  If the color of the node to the west of n is target-color, add that node to the end of Q.
     If the color of the node to the east of n is target-color, add that node to the end of Q.
     If the color of the node to the north of n is target-color, add that node to the end of Q.
     If the color of the node to the south of n is target-color, add that node to the end of Q.
 7. Continue looping until Q is exhausted.
 8. Return.

Most practical implementations use a loop for the west and east directions as an optimization to avoid the overhead of queue management:

Flood-fill (node, target-color, replacement-color):
 1. Set Q to the empty queue.
 2. If the color of node is not equal to target-color, return.
 3. Add node to the end of Q.
 4. For each element n of Q:
 5.  If the color of n is not equal to target-color, skip this iteration.
 6.  Set w and e equal to n.
 7.  Move w to the west until the color of the node to the west of w no longer matches target-color.
 8.  Move e to the east until the color of the node to the east of e no longer matches target-color.
 9.  Set the color of nodes between w and e to replacement-color.
10.  For each node n between w and e:
11.   If the color of the node to the north of n is target-color, add that node to the end of Q.
      If the color of the node to the south of n is target-color, add that node to the end of Q.
12. Continue looping until Q is exhausted.
13. Return.

Adapting the algorithm to use an additional array to store the shape of the region allows generalization to cover "fuzzy" flood filling, where an element can differ by up to a specified threshold from the source symbol. Using this additional array as an alpha channel allows the edges of the filled region to blend somewhat smoothly with the not-filled region.

[edit] Scanline Fill

The algorithm can be sped up by filling lines. Instead of pushing each potential future pixel coordinate into the stack, it inspects the neighbour lines (previous and next) to find adjacent segments that may be filled in a future pass; the coordinates (either the start or the end) of the line segment are pushed on the stack. In most of cases this scanline algorithm is at least an order of magnitude faster than the per-pixel one.

[edit] External links

In other languages