Open Photoshop. Load a photo. Pick the Magic Wand tool. Click on the sky. Instantly, every pixel that “looks like” the sky gets selected — even the bits behind the trees, even the thin strip near the horizon that’s slightly darker. Bump up the tolerance to 40, and it grabs more. Drop it to 5, and it gets picky.
Most people think of this as “Photoshop being smart.” It isn’t smart. It’s running one of the simplest, most beautiful algorithms in computer science — Flood Fill using Breadth-First Search (BFS) — and you’re about to understand every line of it.
The Mental Model
Think of pixels as a grid of rooms
Every image is a grid. Each pixel is a room in that grid. Every room has a colour — say, RGB values like [135, 206, 235] for sky-blue. And every room has four doors — leading to its top, bottom, left, and right neighbours.
When you click the Magic Wand on a pixel, you’re saying: “Start in this room. Visit every neighbouring room that has a similar enough colour. Then visit their neighbours. Keep going until you hit rooms that are too different.”
That’s it. That’s the entire algorithm.
What “Close Enough” Means
The Tolerance slider is just a number comparison
Every pixel has three values: Red, Green, and Blue — each between 0 and 255. When you click a pixel with colour [135, 206, 235] and set tolerance to 30, the algorithm asks a simple question for every neighbour:
The question: Is the difference between the neighbour’s colour and my clicked colour less than or equal to 30?
The “difference” is usually calculated as:|R₁ − R₂| + |G₁ − G₂| + |B₁ − B₂|
This is called Manhattan Distance — named after the city grid, taxicab distance.
If the neighbour pixel is [140, 200, 230], the difference is |135−140| + |206−200| + |235−230| = 5 + 6 + 5 = 16. Since 16 ≤ 30, it’s selected.
If another pixel is [200, 100, 50], the difference is 65 + 106 + 185 = 356. Way over 30. Not selected.
That’s all the tolerance slider does — it changes one number in one comparison.
See It In Action
Here’s a small canvas. Paint some shapes using the colours, then switch to the Magic Wand and click anywhere. Watch it select similar, connected pixels — exactly like Photoshop. Try changing the tolerance to see how it behaves.
The Algorithm: BFS Flood Fill
Why BFS and not just “check everything”?
You might wonder: why not just scan every pixel in the image and select every one that matches the colour? Because the Magic Wand cares about connectedness. It doesn’t select all sky-blue pixels in the image — only the ones that are connected to where you clicked, through a continuous path of similar pixels.
Imagine a photo with a blue sky and a blue car at the bottom. They’re both blue, but separated by buildings. The Magic Wand selects only the sky (connected region), not the car. That’s the power of flood fill — it respects boundaries.
The code, line by line
function magicWand(imageData, startX, startY, tolerance) {
const { width, height, data } = imageData;
const visited = new Uint8Array(width * height);
const selected = [];
// Get the colour of the pixel we clicked
const idx = (startY * width + startX) * 4;
const seedR = data[idx], seedG = data[idx+1], seedB = data[idx+2];
// BFS queue — starts with our clicked pixel
const queue = [[startX, startY]];
visited[startY * width + startX] = 1;
while (queue.length > 0) {
const [x, y] = queue.shift(); // FIFO = BFS
// Compare this pixel's colour to the seed
const i = (y * width + x) * 4;
const diff = Math.abs(data[i] - seedR)
+ Math.abs(data[i+1] - seedG)
+ Math.abs(data[i+2] - seedB);
if (diff <= tolerance) {
selected.push([x, y]); // ✓ This pixel is selected!
// Check all 4 neighbours
for (const [nx, ny] of [[x-1,y],[x+1,y],[x,y-1],[x,y+1]]) {
if (nx >= 0 && nx < width && ny >= 0 && ny < height
&& !visited[ny * width + nx]) {
visited[ny * width + nx] = 1;
queue.push([nx, ny]);
}
}
}
}
return selected;
}
Read it slowly. There’s no magic — just a queue, a loop, and a colour comparison. The queue.shift() is what makes it BFS (first-in, first-out). If you replaced that with queue.pop() (last-in, first-out), you’d get DFS — Depth-First Search — which works too, but explores in a different order.
Watch BFS Explore
Step-by-step animation
This grid has open cells (blue) and walls (dark). Click any blue cell to start a flood fill. Watch the numbered order in which cells are visited — notice how BFS spreads outward in layers, like ripples in water.
BFS vs DFS
| BFS (Breadth-First Search) | DFS (Depth-First Search) |
|---|---|
| Uses a queue (FIFO) | Uses a stack (LIFO) |
| Explores layer by layer — like ripples in a pond | Explores one path as deep as possible, then backtracks |
| Selection grows outward evenly | Selection snakes into one direction first |
| ✅ Photoshop uses this approach | Used in maze solving, game AI pathfinding |
Both give the same final selection. The difference is the order of exploration. BFS feels more natural for visual tools because it spreads evenly — you see the selection “grow” outward from where you clicked.
Where Else Is This Used?
The Paint Bucket tool in any drawing app — MS Paint, GIMP, Figma — is the same algorithm, except instead of “selecting” pixels, it “fills” them with a new colour.
Minesweeper uses flood fill. When you click an empty cell (no adjacent mines), it automatically reveals all connected empty cells. That’s BFS flood fill with the condition “has zero adjacent mines” instead of “colour is close enough.”
Image segmentation in medical imaging uses a more sophisticated version — starting from a seed point (say, a tumour), and growing outward while the tissue characteristics remain similar.
The Tolerance Problem
Why the selection sometimes leaks
If you’ve used the Magic Wand on a photo, you know the frustration: you click the sky, and the selection “leaks” into the white clouds, then into a bright building, then suddenly half the image is selected.
This happens because tolerance is a local comparison — each pixel is compared to the seed colour, not to its immediate neighbour. So a gradual gradient from blue sky → light blue → white → pale grey creates a chain where every adjacent pixel passes the check, even though the starting blue and the ending grey look nothing alike.
Professional tip: This is why Photoshop also offers “Select → Color Range” which lets you sample multiple seed colours, and “Select and Mask” which uses edge detection. Each tool layers a different algorithm on top of this fundamental BFS idea.
Try It Yourself
Challenge
Go to the first demo above and try this experiment: paint a large blue square, then paint a thin red line through the middle of it. Now use the Magic Wand on one side of the blue — notice how the selection stops at the red line, even though both sides are identical blue. That’s the “connected component” property of flood fill at work. The red line is a wall that BFS cannot pass through.
Then gradually increase the tolerance. At some point, the tolerance will be high enough that even the red is considered “close enough” — and the selection will jump across. Finding that tipping point is the essence of understanding tolerance.