Task: Bitmap_Flood fill





Java: import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.Deque;
import java.util.LinkedList;

public class FloodFill {
  public void floodFill(BufferedImage image, Point node, Color targetColor, Color replacementColor) {
    int width = image.getWidth();
    int height = image.getHeight();
    int target = targetColor.getRGB();
    int replacement = replacementColor.getRGB();
    if (target != replacement) {
      Deque<Point> queue = new LinkedList<Point>();
      do {
        int x = node.x;
        int y = node.y;
        while (x > 0 && image.getRGB(x - 1, y) == target) {
          x--;
        }
        boolean spanUp = false;
        boolean spanDown = false;
        while (x < width && image.getRGB(x, y) == target) {
          image.setRGB(x, y, replacement);
          if (!spanUp && y > 0 && image.getRGB(x, y - 1) == target) {
            queue.add(new Point(x, y - 1));
            spanUp = true;
          } else if (spanUp && y > 0 && image.getRGB(x, y - 1) != target) {
            spanUp = false;
          }
          if (!spanDown && y < height - 1 && image.getRGB(x, y + 1) == target) {
            queue.add(new Point(x, y + 1));
            spanDown = true;
          } else if (spanDown && y < height - 1 && image.getRGB(x, y + 1) != target) {
            spanDown = false;
          }
          x++;
        }
      } while ((node = queue.pollFirst()) != null);
    }
  }
}



Python: from collections import deque

image_file = "image.png"
fill_color = color(250, 0, 0)
tolerance = 15
allowed = False

def setup():
    global img
    size(600, 400)
    img = loadImage(image_file)
    fill(0, 0, 100)
    textSize(18)
    show()
    
def show():
    image(img, 0, 0, width, height)
    text("Tolerance = {}    (Use mouse wheel to change)".format(tolerance),
         100, height - 30)
    text("Right click to reset", 100, height - 10)
 
def draw():
    global allowed
    if allowed:
        show()
        allowed = False

def mousePressed():
    global allowed, img
    if mouseButton == RIGHT:
        img = loadImage(image_file)
    else:
        img.loadPixels()
        flood(mouseX, mouseY)
        img.updatePixels()
    allowed = True    

def mouseWheel(event):
    global allowed, tolerance
    e = event.getCount()
    tolerance += 2 * e
    if tolerance > 128:
        tolerance = 128
    if tolerance < 0:
        tolerance = 0
    allowed = True

def flood(x, y):
    target_color = img.pixels[pixel_position(mouseX, mouseY)]
    if target_color != fill_color:
        queue = deque()
        queue.append((x, y))
        while len(queue) > 0:
            p_x, p_y = queue.popleft()
            if (check(p_x, p_y, target_color)):
                queue.append((p_x, p_y - 1))
                queue.append((p_x, p_y + 1))
                queue.append((p_x - 1, p_y))
                queue.append((p_x + 1, p_y))

def pixel_position(x, y):
    return x + (y * img.width)

def check(x, y, target_color):
    if x < 0 or y < 0 or y >= img.height or x >= img.width:
        return False
    pp = img.pixels[pixel_position(x, y)]
    test_tolerance = (abs(green(target_color) - green(pp)) < tolerance
                      and abs(red(target_color) - red(pp)) < tolerance
                      and abs(blue(target_color) - blue(pp)) < tolerance)
    if not test_tolerance:
        return False
    img.pixels[pixel_position(x, y)] = fill_color
    return True