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?
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()