Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Original algorithms by slacky, optimized by Janilabo
- const
- FLOODFILL_8WAY = True; // Fills TPA bounds (polygon outlines)
- FLOODFILL_COLOR = 65535; // ..with this color.
- type
- TFloodFill = (ff4Way, ff8Way);
- procedure __TPAFloodFill4Way(var store: array of TBoolArray; skip: array of TBoolArray; X, Y, W, H: Integer);
- begin
- if ((X > -1) and (Y > -1) and (X < W) and (Y < H)) then
- if not skip[X][Y] then
- if not store[X][Y] then
- begin
- store[X][Y] := True;
- __TPAFloodFill4Way(store, skip, (X - 1), Y, W, H);
- __TPAFloodFill4Way(store, skip, (X + 1), Y, W, H);
- __TPAFloodFill4Way(store, skip, X, (Y - 1), W, H);
- __TPAFloodFill4Way(store, skip, X, (Y + 1), W, H);
- end;
- end;
- procedure __TPAFloodFill8Way(var store: array of TBoolArray; skip: array of TBoolArray; X, Y, W, H: Integer);
- begin
- if ((X > -1) and (Y > -1) and (X < W) and (Y < H)) then
- if not skip[X][Y] then
- if not store[X][Y] then
- begin
- store[X][Y] := True;
- __TPAFloodFill8Way(store, skip, (X - 1), Y, W, H);
- __TPAFloodFill8Way(store, skip, (X + 1), Y, W, H);
- __TPAFloodFill8Way(store, skip, X, (Y - 1), W, H);
- __TPAFloodFill8Way(store, skip, X, (Y + 1), W, H);
- __TPAFloodFill8Way(store, skip, (X - 1), (Y - 1), W, H);
- __TPAFloodFill8Way(store, skip, (X + 1), (Y + 1), W, H);
- __TPAFloodFill8Way(store, skip, (X + 1), (Y - 1), W, H);
- __TPAFloodFill8Way(store, skip, (X - 1), (Y + 1), W, H);
- end;
- end;
- {==============================================================================]
- Explanation: Returns polygon by given outlines (shape)
- NOTE: Original algorithm by slacky (warpie)
- [==============================================================================}
- function TPAFloodFill(TPAOutlines: TPointArray; start: TPoint; method: TFloodFill): TPointArray;
- var
- i, l, r, X, Y, W, H: Integer;
- b: TBox;
- store, skip: array of TBoolArray;
- begin
- l := Length(TPAOutlines);
- if (l > 0) then
- begin
- b := IntToBox(TPAOutlines[0].X, TPAOutlines[0].Y, TPAOutlines[0].X, TPAOutlines[0].Y);
- if (l > 1) then
- for i := 1 to (l - 1) do
- begin
- if (TPAOutlines[i].X < b.X1) then
- b.X1 := TPAOutlines[i].X
- else
- if (TPAOutlines[i].X > b.X2) then
- b.X2 := TPAOutlines[i].X;
- if (TPAOutlines[i].Y < b.Y1) then
- b.Y1 := TPAOutlines[i].Y
- else
- if (TPAOutlines[i].Y > b.Y2) then
- b.Y2 := TPAOutlines[i].Y;
- end;
- if ((start.X >= b.X1) and (start.Y >= b.Y1) and (start.X <= b.X2) and (start.Y <= b.Y2)) then
- begin
- W := ((b.X2 - b.X1) + 1);
- H := ((b.Y2 - b.Y1) + 1);
- SetLength(store, W);
- SetLength(skip, W);
- for i := 0 to (W - 1) do
- begin
- SetLength(skip[i], H);
- SetLength(store[i], H);
- end;
- for i := 0 to (l - 1) do
- skip[(TPAOutlines[i].X - b.X1)][(TPAOutlines[i].Y - b.Y1)] := True;
- case method of
- ff4Way: __TPAFloodFill4Way(store, skip, (start.X - b.X1), (start.Y - b.Y1), W, H);
- ff8Way: __TPAFloodFill8Way(store, skip, (start.X - b.X1), (start.Y - b.Y1), W, H);
- end;
- SetLength(skip, 0);
- SetLength(Result, (W * H));
- for Y := 0 to (H - 1) do
- for X := 0 to (W - 1) do
- if store[X][Y] then
- begin
- Result[r] := Point((X + b.X1), (Y + b.Y1));
- Inc(r);
- end;
- end;
- end;
- SetLength(Result, r);
- end;
- //******* DIRTY EXAMPLE BELLOW: *******//
- procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
- var
- a, z, w, h: Integer;
- begin
- z := High(TPA);
- if (z > -1) then
- begin
- GetBitmapSize(bmp, w, h);
- for a := 0 to z do
- if ((TPA[a].X >= 0) and (TPA[a].Y >= 0) and (TPA[a].X < w) and (TPA[a].Y < h)) then
- FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
- end;
- end;
- function GetBitmapColorTPA(bmp: Integer; color: Integer): TPointArray;
- var
- w, h, x, y, r: Integer;
- begin
- try
- GetBitmapSize(bmp, w, h);
- except
- end;
- if ((w > 0) and (h > 0)) then
- begin
- SetLength(Result, (w * h));
- for y := 0 to (h - 1) do
- for x := 0 to (w - 1) do
- if (FastGetPixel(bmp, x, y) = color) then
- begin
- Result[r] := Point(x, y);
- Inc(r);
- end;
- end;
- SetLength(Result, r);
- end;
- procedure Setup;
- var
- shape, TPA: TPointArray;
- bmp, w, h, t: Integer;
- begin
- bmp := LoadBitmap(ScriptPath + 'example.bmp');
- GetBitmapSize(bmp, w, h);
- TPA := GetBitmapColorTPA(bmp, 0);
- t := GetSystemTime;
- if FLOODFILL_8WAY then
- shape := TPAFloodFill(TPA, MiddleTPA(TPA), ff8Way)
- else
- shape := TPAFloodFill(TPA, MiddleTPA(TPA), ff4Way);
- WriteLn('TPAFloodFill() finished in ' + IntToStr(GetSystemTime - t) + ' ms.');
- SetPixels(bmp, shape, FLOODFILL_COLOR);
- DisplayDebugImgWindow(w, h);
- DrawBitmapDebugImg(bmp);
- FreeBitmap(bmp);
- SetLength(TPA, 0);
- end;
- begin
- Setup;
- end.
Advertisement
Add Comment
Please, Sign In to add comment