2
votes

I've implemented a typical flood fill algorithm and it works as expected when solid colors are used where I use the Euclidean distance between the ARGB components to compare colors.

My problem is that if you draw something like an anti-aliased red line on a transparent background my flood fill algorithm will not fill over most semi-transparent pixels, leaving fringes around objects. Specifically for this example, the center of the line is solid red (i.e. (255, 255, 0, 0) in ARGB format) and the fringes of the line are also solid red but the alpha of these pixels ranges down to 1% alpha (i.e. (1, 255, 0, 0)). Generally, I want to be able to draw, say, a anti-aliased circle outline, flood fill in the center and not have it leave fringes.

What function do I use to compare colors and/or how do I adapt the flood fill algorithm so such fringes are not left around objects?

I've tried telling the algorithm to always fill over a pixel if it's alpha is <90% and this sometimes looks OK but it's too aggressive at filling over faint lines.

Edit: To elaborate what this looks like where 0 - 5 represents a red pixels a 0, 20, 40, 60, 80 and 100% alpha, an image of an anti aliased red line might look like this:

0 0 0 0 0 0 0

0 0 0 3 0 0 0

0 0 3 5 3 0 0

0 0 3 5 3 0 0

0 0 3 5 3 0 0

0 0 0 3 0 0 0

0 0 0 0 0 0 0

My current flood fill algorithm filling red in the top-left corner will replace all the 0s with a 5. The remaining 3s form an ugly looking halo around the line.

1

1 Answers

0
votes

Your flood fill should replace the RGB portions of the colors, but leave the original alpha. That way you get the new color without changing the blending ratio.

(If your bitmap uses pre-multiplied alpha, then you should scale the replacement RGB by the existing alpha, but in your examples, you aren't using pre-multiplied alphas.)