This may not be exactly what you are looking for but you should be able to modify it to suit your needs. It floodfills by a given tolerance, and does so in a continuous manner. It can be shortened down to one single function (or preferably two), but I have written it in the most obvious way, so it's easy to modify and open for optimizations.
Simba Code:
procedure TPointArray.Add(Pt:TPoint);
var L: Integer;
begin
L := Length(Self);
SetLength(Self, L+1);
Self[L] := Pt;
end;
function TPointArray.Pop(): TPoint;
var L: Integer;
begin
L := High(Self);
Result := Self[L];
SetLength(Self, L);
end;
function ConnectedColors(const Img:T2DIntArray; Start:TPoint; Color, Tol, HueTol: Int32): TPointArray;
var
I,j,x,y,W,H:Integer;
face,queue:TPointArray;
Matrix:Array of TBoolArray;
hit: TPoint;
procedure GetAdjacent(var adj:TPointArray; n:TPoint; EightWay:Boolean);
begin
adj[0] := Point(n.x-1,n.y);
adj[1] := Point(n.x,n.y-1);
adj[2] := Point(n.x+1,n.y);
adj[3] := Point(n.x,n.y+1);
if EightWay then
begin
adj[4] := Point(n.x-1,n.y-1);
adj[5] := Point(n.x+1,n.y+1);
adj[6] := Point(n.x-1,n.y+1);
adj[7] := Point(n.x+1,n.y-1);
end;
end;
//redefine me to use other means of comparison.
function CompareColors(colorA, ColorB: Int32; GenTol, HueTol: Int32): Boolean;
var H0,H1,S0,S1,L0,L1: Extended;
begin
ColorToHSL(ColorA, H0,S0,L0);
ColorToHSL(ColorB, H1,S1,L1);
Result := ((Trunc(H1) - Trunc(H0) + 50) mod 100) - 50 <= HueTol;
if not(Result) then Exit;
Result := Abs(L1-L0) + Abs(S1-S0) <= GenTol;
end;
begin
W := Length(Img[0]);
H := Length(Img);
SetLength(Matrix, H, W);
//SetLength(Result, H * W); //PreInit result? Extra mem usage..
SetLength(Face, 8); //4 or 8 (connectivity)
Queue.Add(Start);
while Length(Queue) > 0 do
begin
hit := Queue.Pop;
GetAdjacent(Face, hit, True); //True = 8 way connectivity
for j:=0 to 7 do
begin
x := face[j].x;
y := face[j].y;
if ((x >= 0) and (y >= 0) and (x < W) and (y < H)) then
begin
if (Matrix[y][x] <> True) and
(CompareColors(img[y][x], img[hit.y][hit.x],Tol,HueTol)) then
begin
Matrix[y][x] := True;
Queue.Add(face[j]);
//Result[i] := Point(x, y); //if PreInit
Result.Add(face[j]);
Inc(I);
end;
end;
end;
end;
//SetLength(Result, I); //if PreInit
end;
then.. (pseudocode)
Code:
BMP := BitmapFromClient(...);
TPA := ConnectedColors(BitmapToMatrix(BMP), Point(300, 300), color, Tolernance, HueTolerance);
Hope you are able to modify/use it.