Delphi-Quellcode:
Procedure SearchAreas(Threshold: Byte; Image, Map: TBitMap);
Var LastArea, X, Y, C, C2: Integer;
Begin
Map.PixelFormat := pf24bit;
Map.Width := Image.Width;
Map.Height := Image.Height;
Map.Canvas.Brush.Style := bsSolid;
Map.Canvas.Brush.Color := 0;
Map.Canvas.FillRect(Rect(0, 0, Map.Width, Map.Height));
LastArea := 0;
For Y := 0 to Image.Height - 1 do
For X := 0 to Image.Width - 1 do
If GrayScale(Image.Canvas.Pixels[X, Y]) < Threshold Then Begin
If Y > 0 Then C := Map.Canvas.Pixels[X, Y - 1] Else C := 0;
If C <> 0 Then Begin
Map.Canvas.Pixels[X, Y] := C;
If X > 0 Then C2 := Map.Canvas.Pixels[X - 1, Y] Else C2 := 0;
If (C2 <> 0) and (C2 <> C Then Begin
Map.Canvas.Brush.Color := C;
Map.Canvas.FloodFill(X - 1, Y, C2, fsSurface);
End;
Continue;
End;
If X > 0 Then C := Map.Canvas.Pixels[X - 1, Y] Else C := 0;
If C <> 0 Then Begin
Map.Canvas.Pixels[X, Y] := C;
Continue;
End;
Inc(LastArea);
If LastArea = $01000000 Then Raise EOutOfResources.Create('too many areas');
Map.Canvas.Pixels[X, Y] := LastArea;
End;
End;
Jetzt müßte in
Map ein Image entstehen, welches alle zusammenhängenden Blöcke enthält
Delphi-Quellcode:
// kein zusammenhängender Bereich in/an diesem Pixel
Map.Canvas.Pixels[X, Y] = 0
// hier ist einer und alle Pixel mit dem selben Farbwert gehören dazu
Map.Canvas.Pixels[X, Y] <> 0
Hier werden zwar auch erstmal die 2 genannten Bereiche getrennt aufgeführt, aber sobald ein Zusammenhang erkannt wird, wird per FloodFill ein Zusammenhang geschaffen.
(FloodFill deswegen, weil es diesen Bereich schneller umfärben kann, als man es manuell via Pixels könnte)
PS: Ich hoffe mal 16777215 verschiedene Indize für die Bereiche reichen aus.