Task: Bitmap_Flood fill



C#: using System;
using System.Collections.Generic;
using System.Drawing;

namespace FloodFill
{
    class Program
    {
        private static bool ColorMatch(Color a, Color b)
        {
            return (a.ToArgb() & 0xffffff) == (b.ToArgb() & 0xffffff);
        }

        static void FloodFill(Bitmap bmp, Point pt, Color targetColor, Color replacementColor)
        {
            Queue<Point> q = new Queue<Point>();
            q.Enqueue(pt);
            while (q.Count > 0)
            {
                Point n = q.Dequeue();
                if (!ColorMatch(bmp.GetPixel(n.X, n.Y),targetColor))
                    continue;
                Point w = n, e = new Point(n.X + 1, n.Y);
                while ((w.X >= 0) && ColorMatch(bmp.GetPixel(w.X, w.Y),targetColor))
                {
                    bmp.SetPixel(w.X, w.Y, replacementColor);
                    if ((w.Y > 0) && ColorMatch(bmp.GetPixel(w.X, w.Y - 1),targetColor))
                        q.Enqueue(new Point(w.X, w.Y - 1));
                    if ((w.Y < bmp.Height - 1) && ColorMatch(bmp.GetPixel(w.X, w.Y + 1),targetColor))
                        q.Enqueue(new Point(w.X, w.Y + 1));
                    w.X--;
                }
                while ((e.X <= bmp.Width - 1) && ColorMatch(bmp.GetPixel(e.X, e.Y),targetColor))
                {
                    bmp.SetPixel(e.X, e.Y, replacementColor);
                    if ((e.Y > 0) && ColorMatch(bmp.GetPixel(e.X, e.Y - 1), targetColor))
                        q.Enqueue(new Point(e.X, e.Y - 1));
                    if ((e.Y < bmp.Height - 1) && ColorMatch(bmp.GetPixel(e.X, e.Y + 1), targetColor))
                        q.Enqueue(new Point(e.X, e.Y + 1));
                    e.X++;
                }
            }
        }

        static void Main(string[] args)
        {
            Bitmap bmp = new Bitmap("Unfilledcirc.bmp");
            FloodFill(bmp, new Point(200, 200), Color.White, Color.Red);
            FloodFill(bmp, new Point(100, 100), Color.Black, Color.Blue);
            bmp.Save("Filledcirc.bmp");
        }
    }
}





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