[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]


{
Does anybody know how to do gradient floodfilling?
or a fast floodfill routine?

Here is my floodfill routine, not optimized yet ('cause I am so lazy-grin)
If you feel you can optimize this (I am sure some of you can) and have time to
do so, could you post it back so I can get it from this echo (he he he)

Oh well, some of the procedures and functions in here are not included, like
VSwap - to swap 2 integer variable, GetPixel, PutPixel, I am sure you can
figure out how to create those routines.. now...
I am using link list for tracing, here is the type:
}
type ppixel=^pixel;
     pixel=record
            x,y:integer;
            last:pointer
           end;
{
and here is the routine...
}

procedure floodfill(x,y:integer;c:byte);

var dx,dy,ex,ey,f:integer;
    dc,fc:byte;
    up,down:boolean;
    dot:ppixel;

procedure pushdot(px,py:integer);

var pdot:ppixel;

begin
 new(pdot);
 pdot^.last:=dot;
 pdot^.x:=px;
 pdot^.y:=py;
 dot:=pdot
end;

procedure popdot(var px,py:integer);

var pdot:ppixel;

begin
 pdot:=dot^.last;
 px:=dot^.x;
 py:=dot^.y;
 dispose(dot);
 dot:=pdot
end;

procedure scanline(px1,px2,py:integer;c:byte);

var dpx:integer;

begin
 if px2<px1 then vswap(px1,px2);
 asm
  mov ax,vseg
  mov es,ax
  mov ax,py
  mov dx,320
  mul dx
  add ax,vofs
  mov di,ax
  add di,px1
  mov cx,px2
  sub cx,px1
  inc cx
  mov al,c
  repz stosb
 end
end;

begin
 dot:=nil;
 fc:=getpixel(x,y);
 pushdot(x,y);
 if c<>fc then
 repeat
   down:=on;up:=on;
   popdot(ex,ey);
   dx:=ex;dy:=ey;
   repeat
    if ((getpixel(dx,dy+1)=fc) and down and (dy+1<=199)) then
    begin
     pushdot(dx,dy+1);
     down:=off
    end;
    if ((getpixel(dx,dy-1)=fc) and up and (dy-1>=0)) then
    begin
     pushdot(dx,dy-1);
     up:=off
    end;
    if ((getpixel(dx,dy+1)<>fc) and (not down) and (dy+1<=199)) then down:=on;
    if ((getpixel(dx,dy-1)<>fc) and (not up) and (dy-1>=0)) then up:=on;
    dec(dx)
   until ((getpixel(dx,dy)<>fc) or (dx<0));
   scanline(ex,dx+1,dy,c);
   dx:=ex+1;dy:=ey;
   if getpixel(dx,dy)=fc then
   begin
    down:=on;up:=on;
    repeat
     if ((getpixel(dx,dy+1)=fc) and down and (dy+1<=199)) then
     begin
      pushdot(dx,dy+1);
      down:=off
     end;
     if ((getpixel(dx,dy-1)=fc) and up and (dy-1>=0)) then
     begin
      pushdot(dx,dy-1);
      up:=off
     end;
     if ((getpixel(dx,dy+1)<>fc) and (not down) and (dy+1<=199)) then down:=on;
     if ((getpixel(dx,dy-1)<>fc) and (not up) and (dy-1>=0)) then up:=on;
     inc(dx)
    until ((getpixel(dx,dy)<>fc) or (dx>319));
    scanline(ex,dx-1,dy,c)
   end
 until dot=nil;
end;
{

Phew... Is that messy or what, but hey, it works.  This floodfill doesn't need
a boundary value, it will just fill anything (of the same seed color) until it
encounter a different color (for boundary--any color)

I know somebody asked this b4, but I didn't pay too much attention b4, so, the
2nd question... how do you find the closest RGB value again?
}

[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]