You're creating a new
Bitmap
in each invocation of
GFill
, so you're always looking at the newly created bitmap, not the actual image of the form!
Create
one Bitmap
in
Form1_MouseClick
, copy the initial image of the form into the bitmap, and pass it to
GFill
. Do the filling operation and then call the
g.DrawImageUnscaled(bmp, 0, 0);
after
GFill
returns.
Aside:
GetPixel
and
SetPixel
are
notorously slow. Search here on CodeProject (or with Google) to find better ways of doing this.
[Edit: getting the initial client area bitmap left as an exercise... :-) Google is your friend here!]
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
Graphics g = this.CreateGraphics();
Rectangle rect = this.ClientRectangle;
Bitmap bmp = new Bitmap(rect.Width, rect.Height, g);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
int[] pixels = new int[bmpData.Height * bmpData.Width];
Marshal.Copy(bmpData.Scan0, pixels, 0, pixels.Length);
GFill(Color.Blue.ToArgb(), e.X, e.Y, this.BackColor.ToArgb(), this.ForeColor.ToArgb(), bmp.Width, bmp.Height, pixels);
Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length);
bmp.UnlockBits(bmpData);
g.DrawImageUnscaled(bmp, 0, 0);
}
private void GFill(int newColor, int x, int y, int bcolor, int Fcolor, int width, int height, int[] pixels)
{
if ((x >= 0) && (x < width) && (y >= 0) && (y < height))
{
int offset = x + y * width;
int c = pixels[offset];
if ((c != newColor) && (c != bcolor) && (c != Fcolor))
{
pixels[offset] = newColor;
GFill(newColor, x + 1, y, bcolor, Fcolor, width, height, pixels);
GFill(newColor, x, y + 1, bcolor, Fcolor, width, height, pixels);
GFill(newColor, x - 1, y, bcolor, Fcolor, width, height, pixels);
GFill(newColor, x, y - 1, bcolor, Fcolor, width, height, pixels);
}
}
}
Notice: I added a check for the pixel at x,y already newColor to prevent re-filling areas already done.
This fill routine will overflow the stack fairly quickly!!!