原 简单图像填充算法

填充算法

递归

   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万多层就提示无法创建堆栈防护页。

非递归算法:

        /// <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;
        }

非递归算法,递归转递推。首先图片扩充一圈像素,设置已搜索的标记,简化边界判定。压栈出栈搜索。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏游戏杂谈

as3绘制抛物线

一般做页游的过程中,特效的释放可能是不是固定位置的播放,是需要进行“运动的”(其实就是移动特效这个影响剪辑)。举个例子:步兵射箭,不确定箭发射的方向,事先也不...

972
来自专栏菩提树下的杨过

“AS3.0高级动画编程”学习:第一章高级碰撞检测

AdvancED ActionScript 3.0 Animation 是Keith Peters大师继"Make Things Move"之后的又一力作,网上...

20210
来自专栏菩提树下的杨过

Flash/Flex学习笔记(48):反向运动学(下)

先要复习一下三角函数与余弦定理: 对于直角三角形,三边长a,b,c与三个角A,B,C的关系如下: ? 正弦函数: ? 余弦函数: ? 正切函数: ? 反正切函数...

24010
来自专栏HT

基于HT for Web的3D树的实现

在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到...

1975
来自专栏大大的微笑

java如何根据二进制流确定图片的类型

 为什么需要这样做? 因为仅仅通过后缀名我们并不能得知用户是否把图片的类型更改为其他类型. public enum ImageType { PNG('P','...

5606
来自专栏程序你好

CSharp代码示例每日一讲: 在GDI+中使用填充Fill方法

732
来自专栏GIS讲堂

Arcgis for JS之Cluster聚类分析的实现(基于区域范围的)

咱们书接上文,在上文,实现了基于距离的空间聚类的算法实现,在本文,将继续介绍空间聚类之基于区域范围的实现方式,好了,闲言少叙,先看看具体的效果:

1275
来自专栏逍遥剑客的游戏开发

M2文件头

1162
来自专栏叁金大数据

C#中Image , Bitmap 和 BitmapData

先说Image,Image 就是个图像,不能实例化,提供了位图和源文件操作的函数。本篇文章他就是来打酱油的,这里提供一个Bitmap转成BitmapSource...

1652
来自专栏儿童编程

Python的艺术玩法——“孔雀开屏”篇

本文用Python实现一个“孔雀开屏”的效果,Python也可以这么玩。下面是源码,注释里面的是不同画面的执行代码。

1512

扫码关注云+社区