Have created a flood-fill algorithm for Lua but have trouble converting it to Love.
We have Canvas:getPixel(x,y) but no Canvas:setPixel(x,y,color).
Anyone have a way to set a pixel on a canvas?
love.graphics.point(x,y) only works on the Love's main window (not on a canvas?) and can't use drawing primitives on userdata so can't create boundaries for the fill.
love.graphics.circle only seems to work if radius is >1.
Just overlooking something here.
How to simulate Canvas:setPixel?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: How to simulate Canvas:setPixel?
Did you try drawing a line (x, y, x, y)?
Re: How to simulate Canvas:setPixel?
Yes, didn't work.S0lll0s wrote:Did you try drawing a line (x, y, x, y)?
Re: How to simulate Canvas:setPixel?
imagedata has setPixel, Can you use that instead of a canvas? or creating a 1x1 imagedata and drawing that to the canvas perhaps?
Re: How to simulate Canvas:setPixel?
Haha funny! And I'm too made this one literally 2 days ago. Just for fun. Also only with canvases. Spent half-day on that damn thing. Already written it 20 years ago in Z80 assembly lang and forgot how it was done. Started with recursion then realised that in Lua it is even not needed for this.Ref wrote:Have created a flood-fill algorithm for Lua
You can even take pixels from image from same coordinates and get "texture fill".
Oh. Wait. Correction, I've used ImageData, as veethree proposed.
Code (non optimized of course):
Code: Select all
function love.load()
fill_canvas = love.graphics.newCanvas(100, 100)
love.graphics.setCanvas(fill_canvas)
fill_canvas:clear()
love.graphics.setColor(255, 255, 0)
love.graphics.circle("line", 50, 50, 20)
love.graphics.setCanvas()
fillimage = love.graphics.newImage(fill_canvas:getImageData())
end
function fill(image, x, y, red, green, blue)
if black[1] == nil then
adj = {-1, 0, 1, 0, -1, -1, 0, -1, 1, -1, -1, 1, 0, 1, 1, 1}
pixels = image:getData()
black[#black + 1] = {}
black[#black].x = x
black[#black].y = y
end
while #black > 0 do
x = black[1].x; y = black[1].y
table.remove(black, 1)
pixels:setPixel(x, y, red, green, blue, 255)
for i = 1, #adj, 2 do
-- instead of 100's should be variables, size of image
if x + adj[i] > 0 and x + adj[i] < 100 and y + adj[i + 1] > 0 and y + adj[i + 1] < 100 then
r, g, b, a = pixels:getPixel(x + adj[i], y + adj[i + 1])
if (r == 0 and g == 0 and b == 0) then
pixels:setPixel(x + adj[i], y + adj[i + 1], red, green, blue, 255)
black[#black + 1] = {}
black[#black].x = x + adj[i]
black[#black].y = y + adj[i + 1]
end
end
end
-- fill(image, x, y)
end
end
function love.draw()
black = {}
fill(fillimage, 5, 5, 255, 0, 0)
fill(fillimage, 50, 50, 255, 255, 0)
fillimage = love.graphics.newImage(pixels)
love.graphics.draw(fillimage, 200, 200)
end
- slime
- Solid Snayke
- Posts: 3132
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: How to simulate Canvas:setPixel?
You should use Image:refresh instead of creating a whole new image every frame.
Re: How to simulate Canvas:setPixel?
Oh. Thanks! Useful to know.
Re: How to simulate Canvas:setPixel?
Thanks veethree for the suggestion of using imagedata.
Finally got my flood fill to sort of work - lots of patched code.
Found that Love's primitives leak unless border line width is set to 2.
Surprised that the fill routine is actually fairly fast (don't know what I'm going to use it for!)
See that arampl's code fell into the same trap I did. Changing the color in his 'fill' didn't change the color used because love.graphics.setColor wasn't set to white.
Beware, demo code provided uses a canvas.
Finally got my flood fill to sort of work - lots of patched code.
Found that Love's primitives leak unless border line width is set to 2.
Surprised that the fill routine is actually fairly fast (don't know what I'm going to use it for!)
See that arampl's code fell into the same trap I did. Changing the color in his 'fill' didn't change the color used because love.graphics.setColor wasn't set to white.
Beware, demo code provided uses a canvas.
- Attachments
-
- floodfill.love
- Simple flood-fill algorithm
- (1.31 KiB) Downloaded 87 times
Re: How to simulate Canvas:setPixel?
For one thing it is surely needed - if you want to do image retouching. Load raster image created elsewhere. Non-vector graphics oriented editor.Ref wrote:don't know what I'm going to use it for!
- ArchAngel075
- Party member
- Posts: 319
- Joined: Mon Jun 24, 2013 5:16 am
Re: How to simulate Canvas:setPixel?
flood fill can be useful actually, i do recall needing such a function for template tiles.
ie tile is only white, you can then use code to color parts of tiled (parts specified in a ini or something) and then draw large amounts of variations thanks to such a function.
I have a error to report though,
Reproduction :
flood the entire screen (not the starting shape, but whats around it)
Then hold Rmouse-button and slide over the inner shapes from outside.
Error : main.lua 41
Bad argument #1 to 'draw' (Drawable expected, got nil)
Traceback :
[C] 'draw'
main 41 'draw'
ie tile is only white, you can then use code to color parts of tiled (parts specified in a ini or something) and then draw large amounts of variations thanks to such a function.
I have a error to report though,
Reproduction :
flood the entire screen (not the starting shape, but whats around it)
Then hold Rmouse-button and slide over the inner shapes from outside.
Error : main.lua 41
Bad argument #1 to 'draw' (Drawable expected, got nil)
Traceback :
[C] 'draw'
main 41 'draw'
Who is online
Users browsing this forum: Google [Bot] and 205 guests