Code archives/Graphics/FloodFill - Really!!!
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
FLOODFILL By Adam Novagen After just an hour & a half of typing, I've finally perfected a Flood Fill routine, like those used in paint programs! It can theoretically fill any size image region, and any shape too! Depending on computer configuration, graphics mode, and the number of pixels to be filled, the fill can take anywhere from 5 to 1000 milliseconds (.005 to 1 seconds); just trust the code! HOW TO USE FLOODFILL() FloodFill() is declared like this (not verbatim): FloodFill(Image,Fill X,Fill Y,Fill Red,Fill Green,Fill Blue) Image is the image to be filled; I'm afraid the routine doesn't work directly on graphics buffers. Fill X & Y are the starting coordinates for the fill, and Fill Red, Green and Blue are the RGB color values to fill with. THE TESTING LOOP This file contains a small testing loop at the end. It draws an image of your choice at 0,0, and shows the mouse location with a flashing pixel. Left-clicking on the image will fill that part with a random color; the FloodFill() RGB values in the testing loop are set to Rand(255). The Esc key ends the program, as usual. OPTIONAL CODE The FloodFill() routine contains two sets of optional code, which at the moment has been commented with a semicolon (;). The first line, the interrupt line, is a special "Panic Button" line that lets the Esc key end the program at any point during the execution of FloodFill(). You might want to uncomment this until you have faith in FloodFill's ability to avoid crashes & freezes, but trust me, you won't need it forever! The second bit of optional code lets you watch the fill in action (theoretically.) Depending on your computer configuration, this will probably slow FloodFill() down, but it's worth watching at least once; in a small image, that is! ADDITIONAL FUNCTIONS: PIXELRED/GREEN/BLUE() PixelRed(), PixelGreen(), and PixelBlue() are function used by FloodFill to obtain color information of certain pixels without changing the actual Color R,G,B settings. However, you can also use them like this: PixelRed(Pixel X,Pixel Y) PixelGreen() & Blue() are declared the same way, and all three return a value from 0 to 255. FINAL NOTES All the variables in the FloodFill routine, except for the Pixel type, are preceded by "Ghz_Lib_Var_". This is to minimize the possibility of you accidentally creating a variable with the same name, thus causing FloodFill() or your program to generate bugs. "Ghz_Lib_Var_" is used because FloodFill() and the Pixel functions are all used in the Gigahertz Games Command Library. Gigahertz_Library_Variable = Ghz_Lib_Var, get it? You can mess around with these variables if you really want to get into the FloodFill routine, but I only recommend that for expert Blitzers. Enjoy! | |||||
Type Pixel Field X,Y End Type Function FloodFill(FillImage,FX,FY,FR,FG,FB);COMPLETE If FX < 0 Or FX > ImageWidth(FillImage) - 1 Or FY < 0 Or FY > ImageHeight(FillImage) - 1 RuntimeError("GHZLIB ERROR" + Chr(10) + "Invalid coordinates: " + FX + "," + FY + Chr(10) + "Coords must be within image boundaries") EndIf Local CurrentBuffer = GraphicsBuffer() Local CurrentRed = ColorRed() Local CurrentGreen = ColorGreen() Local CurrentBlue = ColorBlue() SetBuffer ImageBuffer(FillImage) LockBuffer Local TarR = PixelRed(FX,FY) Local TarG = PixelGreen(FX,FY) Local TarB = PixelBlue(FX,FY) Color FR,FG,FB WritePixelFast FX,FY,FB + (FG * 256) + (FR * (256 * 256)) Pixel.Pixel = New Pixel Pixel\X = FX Pixel\Y = FY Repeat Local PixelsRemaining = False For Pixel.Pixel = Each Pixel Local PixelLeft = False Local PixelAbove = False Local PixelRight = False Local PixelBelow = False Local PixelX = Pixel\X Local PixelY = Pixel\Y If Pixel\X > 0;check left If PixelRed(Pixel\X - 1,Pixel\Y) = TarR And PixelGreen(Pixel\X - 1,Pixel\Y) = TarG And PixelBlue(Pixel\X - 1,Pixel\Y) = TarB PixelLeft = True PixelsRemaining = True EndIf EndIf If Pixel\Y > 0;check above If PixelRed(Pixel\X,Pixel\Y - 1) = TarR And PixelGreen(Pixel\X,Pixel\Y - 1) = TarG And PixelBlue(Pixel\X,Pixel\Y - 1) = TarB PixelAbove = True PixelsRemaining = True EndIf EndIf If Pixel\X < ImageWidth(FillImage) - 1;check right If PixelRed(Pixel\X + 1,Pixel\Y) = TarR And PixelGreen(Pixel\X + 1,Pixel\Y) = TarG And PixelBlue(Pixel\X + 1,Pixel\Y) = TarB PixelRight = True PixelsRemaining = True EndIf Else PixelRight = False EndIf If Pixel\Y < ImageHeight(FillImage) - 1;check below If PixelRed(Pixel\X,Pixel\Y + 1) = TarR And PixelGreen(Pixel\X,Pixel\Y + 1) = TarG And PixelBlue(Pixel\X,Pixel\Y + 1) = TarB PixelBelow = True PixelsRemaining = True EndIf Else PixelBelow = False EndIf ;If KeyDown(1) Then End Delete Pixel PixelNum = PixelNum - 1 ;LockBuffer If PixelLeft = True Pixel.Pixel = New Pixel Pixel\X = PixelX - 1 Pixel\Y = PixelY PixelNum = PixelNum + 1 PixelLeft = False WritePixelFast Pixel\X,Pixel\Y,FB + (FG * 256) + (FR * (256 * 256)) EndIf If PixelAbove = True Pixel.Pixel = New Pixel Pixel\X = PixelX Pixel\Y = PixelY - 1 PixelNum = PixelNum + 1 PixelAbove = False WritePixelFast Pixel\X,Pixel\Y,FB + (FG * 256) + (FR * (256 * 256)) EndIf If PixelRight = True Pixel.Pixel = New Pixel Pixel\X = PixelX + 1 Pixel\Y = PixelY PixelNum = PixelNum + 1 PixelRight = False WritePixelFast Pixel\X,Pixel\Y,FB + (FG * 256) + (FR * (256 * 256)) EndIf If PixelBelow = True Pixel.Pixel = New Pixel Pixel\X = PixelX Pixel\Y = PixelY + 1 PixelNum = PixelNum + 1 PixelBelow = False WritePixelFast Pixel\X,Pixel\Y,FB + (FG * 256) + (FR * (256 * 256)) EndIf ;!UNCOMMENT THE FOLLOWING CODE TO SEE FLOODFILL IN ACTION! ;UnlockBuffer ;SetBuffer CurrentBuffer ;DrawImage FillImage,0,0 ;Flip ;SetBuffer ImageBuffer(FillImage) ;LockBuffer Next Until PixelsRemaining = False UnlockBuffer SetBuffer CurrentBuffer Color CurrentRed,CurrentGreen,CurrentBlue End Function Function PixelGreen(Ghz_Lib_Var_PixelX,Ghz_Lib_Var_PixelY) Local Ghz_Lib_Var_CurrentRed = ColorRed() Local Ghz_Lib_Var_CurrentGreen = ColorGreen() Local Ghz_Lib_Var_CurrentBlue = ColorBlue() GetColor(Ghz_Lib_Var_PixelX,Ghz_Lib_Var_PixelY) Local Ghz_Lib_Var_Green = ColorGreen() Color Ghz_Lib_Var_CurrentRed,Ghz_Lib_Var_CurrentGreen,Ghz_Lib_Var_CurrentBlue Return Ghz_Lib_Var_Green End Function Function PixelRed(Ghz_Lib_Var_PixelX,Ghz_Lib_Var_PixelY) Local Ghz_Lib_Var_CurrentRed = ColorRed() Local Ghz_Lib_Var_CurrentGreen = ColorGreen() Local Ghz_Lib_Var_CurrentBlue = ColorBlue() GetColor(Ghz_Lib_Var_PixelX,Ghz_Lib_Var_PixelY) Local Ghz_Lib_Var_Red = ColorRed() Color Ghz_Lib_Var_CurrentRed,Ghz_Lib_Var_CurrentGreen,Ghz_Lib_Var_CurrentBlue Return Ghz_Lib_Var_Red End Function Function PixelBlue(Ghz_Lib_Var_PixelX,Ghz_Lib_Var_PixelY) Local Ghz_Lib_Var_CurrentRed = ColorRed() Local Ghz_Lib_Var_CurrentGreen = ColorGreen() Local Ghz_Lib_Var_CurrentBlue = ColorBlue() GetColor(Ghz_Lib_Var_PixelX,Ghz_Lib_Var_PixelY) Local Ghz_Lib_Var_Blue = ColorBlue() Color Ghz_Lib_Var_CurrentRed,Ghz_Lib_Var_CurrentGreen,Ghz_Lib_Var_CurrentBlue Return Ghz_Lib_Var_Blue End Function ;!TESTING LOOP ;To use this mini-program, just click anywhere on the image. ;The cursor is represented by a flashing pixel. Graphics 800,600,0,2 Global Image = LoadImage("sample image 1.bmp");replace "image.bmp" with a valid filename SetBuffer BackBuffer() SeedRnd MilliSecs() While Not KeyDown(1) Cls If MouseHit(1) Then FloodFill(Image,MouseX(),MouseY(),Rand(255),Rand(255),Rand(255)) DrawImage Image,0,0 Color Rand(255),Rand(255),Rand(255) Plot MouseX(),MouseY();the makeshift cursor Flip Wend End |
Comments
| ||
Very handy, thank you! My pimped up version (for archival purpose): |
Code Archives Forum