To this point we have discussed how to scan covert lines and curves. Suppose that we want to do more than just draw outline figures. We could fill the interior of objects with lines using our line drawing algorithm, or we could draw concentric circles or ellipses with increasingly smaller radii until it appeared to be solid. But this approach is wasteful.
The next class of scan conversion algorithms that we will discuss are the
area-filling algorithms. These algorithms operate on a raster while
completely unaware of any other primatives previously drawn.
The first algorithm, called the parity-fill algorithm, is very simple.
The parity fill algorithm has some notable disadvantages.
Despite all its problems the parity fill algorithm is very popular is some applications, such as fonting and simple polygon drawing. Some reasons are
The first such method that we will discuss is called the boundary-fill algorithm. The boundary-fill method requires the coordinate of a starting point, a fill color, and a background color as arguments.
public void boundaryFill(int x, int y, int fill, int boundary)
{
if ((x < 0) || (x >= raster.width)) return;
if ((y < 0) || (y >= raster.height)) return;
int current = raster.getPixel(x, y);
if ((current != boundary) & (current != fill)) {
raster.setPixel(fill, x, y);
boundaryFill(x+1, y, fill, boundary);
boundaryFill(x, y+1, fill, boundary);
boundaryFill(x-1, y, fill, boundary);
boundaryFill(x, y-1, fill, boundary);
}
}
Note: that this is a recusive routine. Each invocation of
boundaryFill( ) may call itself four more times.
The logic of this routine is very simple. If we are not either on a boundary
or already filled we first fill our point, and then tell our neighbors to fill
themselves.

Left-button click inside one of the regions to start the fill process. I might suggest a starting with a small region. Click the right button to reset the image to its original state
What has happened here? Why is the drawing happening in the order shown? (Hint: consider the algorithm as a tree, with the current pixel as a node and neighoring pixels as ancestors).
Here's the algorithm at full speed.
Left-button click inside one of the regions to start the fill process. Click the right button to reset the image to its original state
public void floodFill(int x, int y, int fill, int old)
{
if ((x < 0) || (x >= raster.width)) return;
if ((y < 0) || (y >= raster.height)) return;
if (raster.getPixel(x, y) == old) {
raster.setPixel(fill, x, y);
floodFill(x+1, y, fill, old);
floodFill(x, y+1, fill, old);
floodFill(x-1, y, fill, old);
floodFill(x, y-1, fill, old);
}
}
Here's the algorithm in action
Left-button click inside one of the regions to start the fill process. Click the right button to reset the image to its original state
public void fillFast(int x, int y, int fill)
{
if ((x < 0) || (x >= raster.width)) return;
if ((y < 0) || (y >= raster.height)) return;
int old = raster.getPixel(x, y);
if (old == fill) return;
raster.setPixel(fill, x, y);
fillEast(x+1, y, fill, old);
fillSouth(x, y+1, fill, old);
fillWest(x-1, y, fill, old);
fillNorth(x, y-1, fill, old);
}
private void fillEast(int x, int y, int fill, int old)
{
if (x >= raster.width) return;
if (raster.getPixel(x, y) == old) {
raster.setPixel(fill, x, y);
fillEast(x+1, y, fill, old);
fillSouth(x, y+1, fill, old);
fillNorth(x, y-1, fill, old);
}
}
private void fillSouth(int x, int y, int fill, int old)
{
if (y >= raster.height) return;
if (raster.getPixel(x, y) == old) {
raster.setPixel(fill, x, y);
fillEast(x+1, y, fill, old);
fillSouth(x, y+1, fill, old);
fillWest(x-1, y, fill, old);
}
}
private void fillWest(int x, int y, int fill, int old)
{
if (x < 0) return;
if (raster.getPixel(x, y) == old) {
raster.setPixel(fill, x, y);
fillSouth(x, y+1, fill, old);
fillWest(x-1, y, fill, old);
fillNorth(x, y-1, fill, old);
}
}
private void fillNorth(int x, int y, int fill, int old)
{
if (y < 0) return;
if (raster.getPixel(x, y) == old) {
raster.setPixel(fill, x, y);
fillEast(x+1, y, fill, old);
fillWest(x-1, y, fill, old);
fillNorth(x, y-1, fill, old);
}
}
And here is the working algorithm.Left-button click inside one of the regions to start the fill process. Click the right button to reset the image to its original state

Here's the code for an eight-connected flood fill.
public void floodFill8(int x, int y, int fill, int old)
{
if ((x < 0) || (x >= raster.width)) return;
if ((y < 0) || (y >= raster.height)) return;
if (raster.getPixel(x, y) == old) {
raster.setPixel(fill, x, y);
floodFill8(x+1, y, fill, old);
floodFill8(x, y+1, fill, old);
floodFill8(x-1, y, fill, old);
floodFill8(x, y-1, fill, old);
floodFill8(x+1, y+1, fill, old);
floodFill8(x-1, y+1, fill, old);
floodFill8(x-1, y-1, fill, old);
floodFill8(x+1, y-1, fill, old);
}
}
Sometimes the eight-connected algorithm gives you exactly what you want.
In the following example try a 8-way connected flood-fill of the
antelope.Left-button click inside one of the regions to start the fill process. Click the right button to reset the image to its original state
Left-button click inside one of the regions to start the fill process. Click the right button to reset the image to its original state