I found the code below on this forum by Caleb P so I definitely do not take any credit for it. It is code for doing a flood fill by replacing one color with another. What I need to do is make this work the same way with an image. I do not know if this is possible. I want to have an image that has a black border in it and make a different fill color. Touch inside on the fill color and have it be replaced with another.
If you can do this let me know your charge and we’ll go from there. Right now I am using the starter version of corona labs if that matters.
Thanks,
Warren
Code:
-------------------------------------------------------------------------------- --[[Pixels A simple POC of "pixel-based" drawing in Corona SDK. Implements a simple queue-based flood fill algorithm. --]] -------------------------------------------------------------------------------- display.setStatusBar(display.HiddenStatusBar) -------------------------------------------------------------------------------- -- Localize -------------------------------------------------------------------------------- local display\_newRect = display.newRect local math\_ceil = math.ceil local table\_insert = table.insert local table\_remove = table.remove -------------------------------------------------------------------------------- -- Variables -------------------------------------------------------------------------------- local canvas = display.newGroup() local pixels = {} local pixelSize = 4 local halfPixelSize = pixelSize \* 0.5 local penRadius = 3 local penPixelRadius = penRadius \* pixelSize local penColor = {r = 1, g = 0, b = 0} local floodFillColor = {r = 0, g = 1, b = 1} local prevEvent -- So that we can track the previous location of touch -------------------------------------------------------------------------------- -- Helper Functions -------------------------------------------------------------------------------- local distanceBetween = function(obj1, obj2) return ((obj2.x - obj1.x) ^ 2 + (obj2.y - obj1.y) ^ 2) ^ 0.5 end local equalColors = function(t1, t2) return (t2.r == t1.r) and (t2.g == t1.g) and (t2.b == t1.b) end local getGridXY = function(x, y) return math\_ceil(x / pixelSize), math\_ceil(y / pixelSize) end -------------------------------------------------------------------------------- -- Make a Pixel -------------------------------------------------------------------------------- local function makePixel(x, y) local pixel = display\_newRect(x \* pixelSize - halfPixelSize, y \* pixelSize - halfPixelSize, pixelSize, pixelSize) pixel.pixelColor = {r = 1, g = 1, b = 1, a = 1} pixel.gridX, pixel.gridY = x, y ------------------------------------------------------------------------------ -- Set Pixel Color ------------------------------------------------------------------------------ function pixel:setPixelColor(r, g, b, a) pixel.pixelColor.r, pixel.pixelColor.g, pixel.pixelColor.b, pixel.pixelColor.a = r, g, b, a or 1 pixel:setFillColor(pixel.pixelColor.r, pixel.pixelColor.g, pixel.pixelColor.b, pixel.pixelColor.a) end pixel:setFillColor(pixel.pixelColor.r, pixel.pixelColor.g, pixel.pixelColor.b, pixel.pixelColor.a) return pixel end -------------------------------------------------------------------------------- -- Get Pixels in Range -------------------------------------------------------------------------------- local function getPixelsInRange(x, y, radius) local p = {} for xPos = x - radius, x + radius do for yPos = y - radius, y + radius do if pixels[xPos] and pixels[xPos][yPos] then table\_insert(p, pixels[xPos][yPos]) end end end return p end -------------------------------------------------------------------------------- -- Color Dot -------------------------------------------------------------------------------- local function colorDot(dotX, dotY) local x, y = getGridXY(dotX, dotY) local pixelsInRange = getPixelsInRange(x, y, penRadius) for i = 1, #pixelsInRange do local pixel = pixelsInRange[i] local dist = distanceBetween(pixel, {x = dotX, y = dotY}) if dist \<= penPixelRadius then pixel:setPixelColor(penColor.r, penColor.g, penColor.b) end end end -------------------------------------------------------------------------------- -- Basic Flood Fill -------------------------------------------------------------------------------- local function floodFill(x, y, targetColor, replacementColor) if equalColors(targetColor, replacementColor) then return end if pixels[x] and pixels[x][y] then local queue = {} local processed = {} table\_insert(queue, pixels[x][y]) while #queue \> 0 do local topNode = table\_remove(queue, #queue) if equalColors(topNode.pixelColor, targetColor) then topNode:setPixelColor(replacementColor.r, replacementColor.g, replacementColor.b) local gridX, gridY = topNode.gridX, topNode.gridY processed[gridX] = processed[gridX] or {} processed[gridX][gridY] = true if pixels[gridX - 1] and pixels[gridX - 1][gridY] and (not processed[gridX - 1] or not processed[gridX - 1][gridY]) then table\_insert(queue, pixels[gridX - 1][gridY]) end if pixels[gridX] and pixels[gridX][gridY - 1] and (not processed[gridX] or not processed[gridX][gridY - 1]) then table\_insert(queue, pixels[gridX][gridY - 1]) end if pixels[gridX + 1] and pixels[gridX + 1][gridY] and (not processed[gridX + 1] or not processed[gridX + 1][gridY]) then table\_insert(queue, pixels[gridX + 1][gridY]) end if pixels[gridX] and pixels[gridX][gridY + 1] and (not processed[gridX] or not processed[gridX][gridY + 1]) then table\_insert(queue, pixels[gridX][gridY + 1]) end end end end end -------------------------------------------------------------------------------- -- Touch Listener -------------------------------------------------------------------------------- local function onTouch(event) if "began" == event.phase then display.getCurrentStage():setFocus(canvas) canvas.isFocus = true prevEvent = event penColor = {r = math.random(), g = math.random(), b = math.random()} elseif canvas.isFocus then if "moved" == event.phase then local dist = distanceBetween(event, prevEvent) / pixelSize local xAdd = (prevEvent.x - event.x) / dist local yAdd = (prevEvent.y - event.y) / dist for i = 1, dist do colorDot(event.x + xAdd \* i, event.y + yAdd \* i) end prevEvent = event elseif "ended" == event.phase or "cancelled" == event.phase then end end end -------------------------------------------------------------------------------- -- Tap Listener -------------------------------------------------------------------------------- local function onTap(event) if event.numTaps == 2 then local x, y = getGridXY(event.x, event.y) if pixels[x] and pixels[x][y] then floodFillColor = {r = math.random(), g = math.random(), b = math.random()} local pxColor = pixels[x][y].pixelColor floodFill(x, y, {r = pxColor.r, g = pxColor.g, b = pxColor.b}, floodFillColor) end end end -------------------------------------------------------------------------------- -- Draw Pixels -------------------------------------------------------------------------------- for x = 1, display.contentWidth / pixelSize do pixels[x] = {} for y = 1, display.contentHeight / pixelSize do pixels[x][y] = makePixel(x, y) canvas:insert(pixels[x][y]) end end Runtime:addEventListener("touch", onTouch) Runtime:addEventListener("tap", onTap)