Recursive function works on Windows 2000, but not on Win2003 server

M

Martin Holmgaard

I have written the following function to be used for flood filling in
a bitmap. The function works fine on Windows XP Prof and Windows 2000
server, but on Windows 2003 server it return a stack overflow if the
function runs recursive more than 5495 times. Does anyone know a
solution on the problem eg. how to extend the stack size on Windows
2003, or better a non-recursive function for flood filling an image ?

Function fncFloodFill(ByVal XStart As Long, ByVal YStart As Long,
ByVal fillColor As Color, ByVal oldColor As Color)
Dim Red As Long = objBitmap2.GetPixel(XStart, YStart).R
Dim Green As Long = objBitmap2.GetPixel(XStart, YStart).G
Dim Blue As Long = objBitmap2.GetPixel(XStart, YStart).B

If Red = oldColor.R Then
If Green = oldColor.G Then
If Blue = oldColor.B Then
objBitmap2.SetPixel(XStart, YStart, fillColor)

If XStart + 1 <= objBitmap2.Width Then
fncFloodFill(XStart + 1, YStart, fillColor,
oldColor)
End If

If XStart - 1 >= 0 Then
fncFloodFill(XStart - 1, YStart, fillColor,
oldColor)
End If

If YStart + 1 <= objBitmap2.Height Then
fncFloodFill(XStart, YStart + 1, fillColor,
oldColor)
End If

If YStart - 1 >= 0 Then
fncFloodFill(XStart, YStart - 1, fillColor,
oldColor)
End If
End If
End If
End If
 
G

Guest

Hi Martin,

I can't confess to knowing exactly what you're attempting to accomplish, but
have you considered possibily using a loop instead of recursion? 5495
entries on the call stack is quite a few. As far as I can tell you're just
changing the X and Y start positions which I would think could be easily done
with a few nested loops.

You may have a good reason, I just can't see it right off.
 
R

Robbe Morris [C# MVP]

I don't about your win2k3 server error. What I do know is
that .GetPixel() and .SetPixel() are expensive. I "suspect" your
code is probably calling .GetPixel() more often than it really needs
to on quite a few pixels.

I did something "sort of similar" to what you are doing when
evaluating the contents of an image pixel by pixel. Take a
look at this sample and how I went through the image once,
captured the colors for each pixel. Then, used the array
in my evaluation code... You could also test to see if a pixel
has already had .SetPixel() run on it prior to actually calling the method.

http://www.eggheadcafe.com/articles/20031218.asp

--
2005 Microsoft MVP C#
Robbe Morris
http://www.robbemorris.com
http://www.mastervb.net/home/ng/forumvbcode/post10017013.aspx
http://www.eggheadcafe.com/articles/adonet_source_code_generator.asp
 
M

Martin Holmgaard

Thanks, but it didn't solve my problem. Even if I place the
pixelvalues in 3 arrays, I stille get the error.

For intX = 0 To objBitmap2.Width - 1
For intY = 0 To objBitmap2.Height - 1
pixelR(intX, intY) = objBitmap2.GetPixel(intX, intY).R
pixelG(intX, intY) = objBitmap2.GetPixel(intX, intY).G
pixelB(intX, intY) = objBitmap2.GetPixel(intX, intY).B
Next
Next

Function fncFloodFill(ByVal XStart As Long, ByVal YStart As Long,
ByVal fillColor As Color, ByVal oldColor As Color)
'red = objBitmap2.GetPixel(XStart, YStart).R
'green = objBitmap2.GetPixel(XStart, YStart).G
'blue = objBitmap2.GetPixel(XStart, YStart).B
red = pixelR(XStart, YStart)
green = pixelG(XStart, YStart)
blue = pixelB(XStart, YStart)

If red = oldColor.R Then
If green = oldColor.G Then
If blue = oldColor.B Then
pixelR(XStart, YStart) = fillColor.R
pixelG(XStart, YStart) = fillColor.G
pixelB(XStart, YStart) = fillColor.B
objBitmap2.SetPixel(XStart, YStart, fillColor)

If XStart + 1 <= objBitmap2.Width Then
fncFloodFill(XStart + 1, YStart, fillColor,
oldColor)
End If

If XStart - 1 >= 0 Then
fncFloodFill(XStart - 1, YStart, fillColor,
oldColor)
End If

If YStart + 1 <= objBitmap2.Height Then
fncFloodFill(XStart, YStart + 1, fillColor,
oldColor)
End If

If YStart - 1 >= 0 Then
fncFloodFill(XStart, YStart - 1, fillColor,
oldColor)
End If
End If
End If
End If
End Function
 
M

Martin Holmgaard

Solved the problem, by using the following FloodFill function in
asp.net C#. Thanks to D. de Haas

/// <summary>
/// ExtGraphics
/// D. de Haas
/// 28 november 2003
/// </summary>

public class ExtGraphics
{
private Bitmap bmp;
private Color bc;

public ExtGraphics(Bitmap b)
{
this.bmp = b;
}

public bool FloodFill(int X, int Y, Color fillColor)
{
if((X < 0) || (X >= bmp.Width) || (Y < 0) || (Y >= bmp.Height))
return false;

bc = bmp.GetPixel(X, Y);
if (bc.ToArgb() == fillColor.ToArgb()) return false;

Stack points = new Stack();

points.Push(new Point(X ,Y));
do
{
Point p = (Point)points.Pop();
bmp.SetPixel(p.X, p.Y, fillColor);

if(this.CanUp(p.X, p.Y)) points.Push(new Point(p.X, p.Y - 1));
if(this.CanRight(p.X, p.Y)) points.Push(new Point(p.X + 1, p.Y));
if(this.CanDown(p.X, p.Y)) points.Push(new Point(p.X, p.Y + 1));
if(this.CanLeft(p.X, p.Y)) points.Push(new Point(p.X - 1, p.Y));
}
while(points.Count > 0);

return true;
}


private bool CanUp(int X, int Y)
{
return((Y > 0) && bmp.GetPixel(X, Y - 1) == bc);
}

private bool CanRight(int X, int Y)
{
return((X < bmp.Width-1) && bmp.GetPixel(X + 1, Y) == bc);
}

private bool CanDown(int X, int Y)
{
return((Y < bmp.Height-1) && bmp.GetPixel(X, Y + 1) == bc);
}

private bool CanLeft(int X, int Y)
{
return((X > 0) && bmp.GetPixel(X - 1, Y) == bc);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top