簡單圖像填充算法

填充算法算法

遞歸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;
        }

非遞歸算法,遞歸轉遞推。首先圖片擴充一圈像素,設置已搜索的標記,簡化邊界斷定。壓棧出棧搜索。遞歸

測試結果圖片

相關文章
相關標籤/搜索