填充算法算法
遞歸c#
private void fillsearch(Bitmap bmp, int x, int y, byte[,] flag,int num) { //向左 若是爲1返回 若是不是1 計算當前值 若是不在範圍內設爲1返回 而且向下遞歸 if (Math.Abs(bmp.GetPixel(x, y).B - num) >50) { flag[x, y] = 2; return; } else { flag[x, y] =1; } if (0 ==x || x == bmp.Width-1) return; if(0==y||y==bmp.Height-1) return; if (flag[x - 1, y] == 0) { fillsearch(bmp, x - 1, y, flag, num); } if (flag[x, y-1] == 0) { fillsearch(bmp, x , y-1, flag, num); } if (flag[x+1, y] == 0) { fillsearch(bmp, x+1, y, flag, num); } if (flag[x , y+1] == 0) { fillsearch(bmp, x , y+1, flag, num); } }
遞歸算法不太好用,小圖片還能夠。大圖片個人機器上遞歸到1萬多層就提示沒法建立堆棧防禦頁。測試
非遞歸算法:code
/// <summary> /// 填充算法 /// </summary> /// <param name="bmp"></param> /// <param name="x"></param> /// <param name="y"></param> private Bitmap fillin(Bitmap bmp, int x, int y) { Bitmap map = new Bitmap(bmp.Width+2,bmp.Height+2); for (int i = 0; i < bmp.Width; i++) { for (int j = 0; j < bmp.Height; j++) { map.SetPixel(i + 1, j + 1, bmp.GetPixel(i, j)); } } Byte[,] flag=new Byte[bmp.Width+2,bmp.Height+2]; for (int i = 0; i < map.Width; i++) { for (int j = 0; j < map.Height; j++) { flag[i, j] = 0; } } for (int i = 0; i < map.Width; i++) { flag[i, 0] = 2; flag[i, map.Height-1] = 2; } for (int i = 0; i < map.Height; i++) { flag[0, i] = 2; flag[map.Width-1, i] = 2; } Stack<Point> colors = new Stack<Point>(); colors.Push(new Point(x,y)); int colorB = map.GetPixel(x, y).B; while (colors.Count != 0) { x--; if (flag[x, y] == 0) { if (Math.Abs(map.GetPixel(x, y).B - colorB) > 50) { flag[x, y] = 2; } else { flag[x, y] = 1; colors.Push(new Point(x, y)); continue; } } else { x++; } y--; if (flag[x, y] == 0) { if (Math.Abs(map.GetPixel(x, y).B - colorB) > 50) { flag[x, y] = 2; } else { flag[x, y] = 1; colors.Push(new Point(x, y)); continue; } } else { y++; } x++; if (flag[x, y] == 0) { if (Math.Abs(map.GetPixel(x, y).B - colorB) > 50) { flag[x, y] = 2; } else { flag[x, y] = 1; colors.Push(new Point(x, y)); continue; } } else { x--; } y++; if (flag[x, y] == 0) { if (Math.Abs(map.GetPixel(x, y).B - colorB) > 50) { flag[x, y] = 2; } else { flag[x, y] = 1; colors.Push(new Point(x, y)); continue; } } else { y--; } Point p= colors.Pop(); x = p.X; y = p.Y; } Bitmap b = (Bitmap)bmp.Clone(); for (int i = 0; i < b.Width; i++) { for (int j = 0; j < b.Height; j++) { if (flag[i+1,j+1] == 1) { b.SetPixel(i, j, Color.FromArgb(255, 0, 0)); } else if (flag[i+1, j+1] == 2) { b.SetPixel(i, j, Color.FromArgb(0, 255 , 0)); } else { b.SetPixel(i, j, Color.FromArgb(0, 0, 255)); } } } return b; }
非遞歸算法,遞歸轉遞推。首先圖片擴充一圈像素,設置已搜索的標記,簡化邊界斷定。壓棧出棧搜索。遞歸
測試結果圖片