Optimize flood fill algorithm

- Reduced memory usage.
- 20% faster than the original implementation.
This commit is contained in:
Naveen 2023-03-11 05:50:58 +05:30
parent 21d9ec3650
commit 50f3442122
1 changed files with 13 additions and 24 deletions

View File

@ -96,48 +96,30 @@ class VectorFloodFiller(image: Bitmap) {
var lFillLoc = x // the location to check/fill on the left
var pxIdx = width * y + x
path.moveTo(x.toFloat(), y.toFloat())
while (true) {
// fill with the color
val newX = (pxIdx % width).toFloat()
val newY = (pxIdx - newX) / width
path.lineTo(newX, newY)
// indicate that this pixel has already been checked and filled
pixelsChecked[pxIdx] = true
// de-increment
lFillLoc-- // de-increment counter
pxIdx-- // de-increment pixel index
lFillLoc--
pxIdx--
// exit loop if we're at edge of bitmap or color area
if (lFillLoc < 0 || pixelsChecked[pxIdx] || !isPixelColorWithinTolerance(pxIdx)) {
break
}
}
vectorFill(pxIdx + 1)
lFillLoc++
// Find Right Edge of Color Area
var rFillLoc = x // the location to check/fill on the left
pxIdx = width * y + x
while (true) {
// fill with the color
val newX = (pxIdx % width).toFloat()
val newY = (pxIdx - newX) / width
path.lineTo(newX, newY)
// indicate that this pixel has already been checked and filled
pixelsChecked[pxIdx] = true
// increment
rFillLoc++ // increment counter
pxIdx++ // increment pixel index
// exit loop if we're at edge of bitmap or color area
rFillLoc++
pxIdx++
if (rFillLoc >= width || pixelsChecked[pxIdx] || !isPixelColorWithinTolerance(pxIdx)) {
break
}
}
vectorFill(pxIdx - 1)
rFillLoc--
// add range to queue
@ -145,6 +127,13 @@ class VectorFloodFiller(image: Bitmap) {
ranges.offer(r)
}
// vector fill pixels with color
private fun vectorFill(pxIndex: Int) {
val x = (pxIndex % width).toFloat()
val y = (pxIndex - x) / width
path.lineTo(x, y)
}
// Sees if a pixel is within the color tolerance range.
private fun isPixelColorWithinTolerance(px: Int): Boolean {
val red = pixels!![px] ushr 16 and 0xff