110,566
社区成员
发帖
与我相关
我的任务
分享
public Bitmap FloodFill(Bitmap src, Point location, Color fillColor, int threshould)
{
try
{
Bitmap a = new Bitmap(src);
int w = a.Width;
int h = a.Height;
Stack<Point> fillPoints = new Stack<Point>(w * h);
System.Drawing.Imaging.BitmapData bmpData = a.LockBits(new Rectangle(0, 0, a.Width, a.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
IntPtr ptr = bmpData.Scan0;
int stride = bmpData.Stride;
int bytes = bmpData.Stride * a.Height;
int r = fillColor.R;
int g=fillColor.G;
int b=fillColor.B;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
byte[] temp = (byte[])grayValues.Clone();
Color backColor = Color.FromArgb(temp[location.X * 3 + 2 + location.Y * stride], temp[location.X * 3 + 1 + location.Y * stride], temp[location.X * 3 + location.Y * stride]);
int gray = (int)((backColor.R + backColor.G + backColor.B) / 3);
if (location.X < 0 || location.X >= w || location.Y < 0 || location.Y >= h) return null;
fillPoints.Push(new Point(location.X, location.Y));
int[,] mask = new int[w, h];
while (fillPoints.Count > 0)
{
Point p = fillPoints.Pop();
mask[p.X, p.Y] = 1;
temp[3 * p.X + p.Y * stride] = (byte)fillColor.B;
temp[3 * p.X + 1 + p.Y * stride] = (byte)fillColor.G;
temp[3 * p.X + 2 + p.Y * stride] = (byte)fillColor.R;
if (p.X > 0 && (Math.Abs(gray - (int)((temp[3 * (p.X - 1) + p.Y * stride] + temp[3 * (p.X - 1) + 1 + p.Y * stride] + temp[3 * (p.X - 1) + 2 + p.Y * stride]) / 3)) < threshould) && (mask[p.X - 1, p.Y] != 1))
{
temp[3 * (p.X - 1) + p.Y * stride] = (byte)fillColor.B;
temp[3 * (p.X - 1) + 1 + p.Y * stride] = (byte)fillColor.G;
temp[3 * (p.X - 1) + 2 + p.Y * stride] = (byte)fillColor.R;
fillPoints.Push(new Point(p.X - 1, p.Y));
mask[p.X - 1, p.Y] = 1;
}
if (p.X < w - 1 && (Math.Abs(gray - (int)((temp[3 * (p.X + 1) + p.Y * stride] + temp[3 * (p.X + 1) + 1 + p.Y * stride] + temp[3 * (p.X + 1) + 2 + p.Y * stride]) / 3)) < threshould) && (mask[p.X + 1, p.Y] != 1))
{
temp[3 * (p.X + 1) + p.Y * stride] = (byte)fillColor.B;
temp[3 * (p.X + 1) + 1 + p.Y * stride] = (byte)fillColor.G;
temp[3 * (p.X + 1) + 2 + p.Y * stride] = (byte)fillColor.R;
fillPoints.Push(new Point(p.X + 1, p.Y));
mask[p.X + 1, p.Y] = 1;
}
if (p.Y > 0 && (Math.Abs(gray - (int)((temp[3 * p.X + (p.Y - 1) * stride] + temp[3 * p.X + 1 + (p.Y - 1) * stride] + temp[3 * p.X + 2 + (p.Y - 1) * stride]) / 3)) < threshould) && (mask[p.X, p.Y - 1] != 1))
{
temp[3 * p.X + (p.Y - 1) * stride] = (byte)fillColor.B;
temp[3 * p.X + 1 + (p.Y - 1) * stride] = (byte)fillColor.G;
temp[3 * p.X + 2 + (p.Y - 1) * stride] = (byte)fillColor.R;
fillPoints.Push(new Point(p.X, p.Y - 1));
mask[p.X, p.Y - 1] = 1;
}
if (p.Y < h - 1 && (Math.Abs(gray - (int)((temp[3 * p.X + (p.Y + 1) * stride] + temp[3 * p.X + 1 + (p.Y + 1) * stride] + temp[3 * p.X + 2 + (p.Y + 1) * stride]) / 3)) < threshould) && (mask[p.X, p.Y + 1] != 1))
{
temp[3 * p.X + (p.Y + 1) * stride] = (byte)fillColor.B;
temp[3 * p.X + 1 + (p.Y + 1) * stride] = (byte)fillColor.G;
temp[3 * p.X + 2 + (p.Y + 1) * stride] = (byte)fillColor.R;
fillPoints.Push(new Point(p.X, p.Y + 1));
mask[p.X, p.Y + 1] = 1;
}
}
fillPoints.Clear();
grayValues = (byte[])temp.Clone();
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
a.UnlockBits(bmpData);
return a;
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
return null;
}
}