namespace FloodFill
{
public partial class Form1 : Form
{
...
public void FloodFill(Bitmap bmp, Point pt, Color fillcolor)
{
if (bmp.GetPixel(pt.X, pt.Y).ToArgb() != fillcolor.ToArgb())
{
int m_fillcolor = 255 << 8;
byte[] m_Tolerance = new byte[] { 32, 32, 32 };
bool[,] PixelsChecked;
Queue CheckQueue = new Queue();
m_fillcolor = ColorTranslator.ToWin32(fillcolor);
m_fillcolor = (int)((byte)((byte)(short)((m_fillcolor >> 16) & 0xffff) & 0xff) + ((byte)(((short)(short)(m_fillcolor & 0xffff) >> 8) & 0xff) << 8) + ((byte)((byte)(short)(m_fillcolor & 0xffff) & 0xff) << 16) + ((byte)(((byte)(short)((m_fillcolor >> 16) & 0xffff) >> 8) & 0xff) << 24));
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
System.IntPtr Scan0 = bmpData.Scan0;
unsafe
{
byte* scan0 = (byte*)(void*)Scan0;
int loc = (bmpData.Stride * pt.Y) + (pt.X * 4);
int color = *((int*)(scan0 + loc));
PixelsChecked = new bool[bmpData.Width + 1, bmpData.Height + 1];
Size bmpsize = new Size(bmpData.Width, bmpData.Height);
CheckQueue = new Queue();
byte* btcolor2 = (byte*)&color;
if (!((pt.X < 0) || (pt.X >= bmpsize.Width) || (pt.Y < 0) || (pt.Y >= bmpsize.Height)))
{
int* p1 = (int*)(scan0 + (bmpData.Stride * pt.Y) + (pt.X * 4));
bool ret1 = true;
byte* px1 = (byte*)p1;//change point to byte
for (byte i = 0; i < 3; i++)
{
ret1 &= (px1[i] >= (btcolor2[i] - m_Tolerance[i])) && px1[i] <= (btcolor2[i] + m_Tolerance[i]);
}
if (!(PixelsChecked[pt.X, pt.Y]) && ret1)
{
p1[0] = m_fillcolor; //fill with the color
PixelsChecked[pt.X, pt.Y] = true;
CheckQueue.Enqueue(new Point(pt.X + 1, pt.Y));
CheckQueue.Enqueue(new Point(pt.X, pt.Y + 1));
CheckQueue.Enqueue(new Point(pt.X - 1, pt.Y));
CheckQueue.Enqueue(new Point(pt.X, pt.Y - 1));
}
}
while (CheckQueue.Count > 0)
{
Point pt2 = (Point)CheckQueue.Dequeue();
if (!((pt2.X < 0) || (pt2.X >= bmpsize.Width) || (pt2.Y < 0) || (pt2.Y >= bmpsize.Height)))
{
byte* btcolor = (byte*)&color;
int* p = (int*)(scan0 + (bmpData.Stride * pt2.Y) + (pt2.X * 4));
bool ret = true;
byte* px = (byte*)p;//change point to byte
for (byte i = 0; i < 3; i++)
{
ret &= (px[i] >= (btcolor[i] - m_Tolerance[i])) && px[i] <= (btcolor[i] + m_Tolerance[i]);
}
if (!(PixelsChecked[pt2.X, pt2.Y]) && ret)
{
p[0] = m_fillcolor; //fill with the color
PixelsChecked[pt2.X, pt2.Y] = true;
CheckQueue.Enqueue(new Point(pt2.X + 1, pt2.Y));
CheckQueue.Enqueue(new Point(pt2.X, pt2.Y + 1));
CheckQueue.Enqueue(new Point(pt2.X - 1, pt2.Y));
CheckQueue.Enqueue(new Point(pt2.X, pt2.Y - 1));
}
}
}
}
bmp.UnlockBits(bmpData);
}
}
//将一个图片放到窗口中去。下面是单击事件
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
FloodFill((Bitmap)pictureBox1.Image, new Point(e.X, e.Y), Color.LightPink);
pictureBox1.Refresh();
}
}
}