Is there a way to achieve FloodFill to also fill the surrounding pixels with near-similar colors?
Preferably by being able to set a threshold value to control this.
Something like the threshold setting found in Gimp.
If not, would this be possible to add as an option to FloodFill in the future?
FloodFill with threshold possible?
Re: FloodFill with threshold possible?
Deepseek came up with a way to floodfill with a threshold value.
I asked it to make a small example of a working code that loads a 640x480 testimage and floodfills it with RED color in the area where clicked, and to use a threshold variable to also fill similar colors. After quite a lot of corrections, the code is working. The Filling process is quite slow but it does what it was asked to. Setting the threshold value to 0 will only fill the exact same color.
Here is the working code:
Any suggestions to speed up the process?
I asked it to make a small example of a working code that loads a 640x480 testimage and floodfills it with RED color in the area where clicked, and to use a threshold variable to also fill similar colors. After quite a lot of corrections, the code is working. The Filling process is quite slow but it does what it was asked to. Setting the threshold value to 0 will only fill the exact same color.
Here is the working code:
Any suggestions to speed up the process?
Code: Select all
@DISPLAY {Title = "Flood Fill with Threshold", Width = 640, Height = 480, Color = #WHITE}
; Constants
CANVAS_WIDTH = 640
CANVAS_HEIGHT = 480
; Global variables
Global activeBrush
Global threshold = 1 ; Default threshold (1-100)
Global colorToFill = #RED ; Default fill color
; Function to calculate the color difference between two colors
Function ColorDifference(color1, color2)
; If the colors are identical, return 0
If color1 = color2
Return(0)
EndIf
; Extract RGB components from color1
r1 = (color1 >> 16) & 255
g1 = (color1 >> 8) & 255
b1 = color1 & 255
; Extract RGB components from color2
r2 = (color2 >> 16) & 255
g2 = (color2 >> 8) & 255
b2 = color2 & 255
; Calculate the Euclidean distance between the two colors
diff = Sqrt((r1 - r2)^2 + (g1 - g2)^2 + (b1 - b2)^2)
; Normalize the difference to a range of 0-100
normalizedDiff = (diff / 441.67) * 100
Return(normalizedDiff)
EndFunction
; Custom flood fill function with threshold
Function FloodFillWithThreshold(x, y, targetColor, fillColor, threshold)
; Create a stack for storing pixels to process
stack = CreateList()
InsertItem(stack, {x = x, y = y})
; Create a visited matrix to avoid reprocessing pixels
visited = {} ; Use a table to simulate a 2D array
For Local i = 0 To CANVAS_WIDTH - 1
visited[i] = {}
For Local j = 0 To CANVAS_HEIGHT - 1
visited[i][j] = False
Next
Next
; Process the stack
While ListItems(stack) > 0
; Pop the last pixel from the stack
pixel = RemoveItem(stack, ListItems(stack) - 1)
x = pixel.x
y = pixel.y
; Check if the pixel is within bounds
If x >= 0 And x < CANVAS_WIDTH And y >= 0 And y < CANVAS_HEIGHT
; Check if the pixel has already been visited
If Not visited[x][y]
; Get the color of the current pixel from the brush
currentColor = ReadBrushPixel(activeBrush, x, y)
; Calculate the color difference
diff = ColorDifference(currentColor, targetColor)
If IsNil(diff)
Else
; Check if the color difference is within the threshold
If diff <= threshold
; Set the pixel in the brush to the fill color
SelectBrush(activeBrush)
Line(x, y, x, y, fillColor)
; Mark the pixel as visited
visited[x][y] = True
; Add neighboring pixels to the stack
InsertItem(stack, {x = x + 1, y = y})
InsertItem(stack, {x = x - 1, y = y})
InsertItem(stack, {x = x, y = y + 1})
InsertItem(stack, {x = x, y = y - 1})
EndIf
EndIf
; Increment the debug counter
debugCounter = debugCounter + 1
EndIf
EndIf
Wend
EndFunction
; Main program
Function p_Main()
; Load the test image with an explicit brush ID (or use NIL for auto-assign)
activeBrush = LoadBrush(Nil, "testfile.png")
If activeBrush = Nil
DebugPrint("Error: Could not load testfile.png!")
Return
EndIf
; Display the loaded brush
DisplayBrush(activeBrush, 0, 0)
; Main loop
Repeat
; Wait for a mouse click event
WaitLeftMouse
; Get the mouse position
x = MouseX()
y = MouseY()
; Check if the click is within the canvas bounds
If x >= 0 And x < CANVAS_WIDTH And y >= 0 And y < CANVAS_HEIGHT
; Get the target color at the clicked pixel from the brush
targetColor = ReadBrushPixel(activeBrush, x, y)
; Perform the flood fill with the specified threshold and color
FloodFillWithThreshold(x, y, targetColor, colorToFill, threshold)
; Update the display
DisplayBrush(activeBrush, 0, 0)
EndIf
Forever
EndFunction
; Run the program
p_Main()
- airsoftsoftwair
- Posts: 5830
- Joined: Fri Feb 12, 2010 2:33 pm
- Location: Germany
- Contact: