c# 一种图像填充算法
算法来源: https://pengfeixc.com/blog/60d06420e97367196dce3efb
非常感谢提供这么优秀的算法, 因为文章里面只有思路, 我写成了C# 代码,
public void seedFillFast(Point pointseed, Color fillcolor, Bitmap bitmap) { //种子点的坐标必须在图片范围内 if (pointseed.X < 0 || pointseed.X > bitmap.Width || pointseed.Y < 0 || pointseed.Y > bitmap.Height) return; Color backgroundColor = bitmap.GetPixel(pointseed.X, pointseed.Y); //如果背景颜色和填充颜色一样,直接返回 if (backgroundColor == fillcolor) return; //1, 创建一个栈, 将起始点压入栈 Stack<Point> stack = new Stack<Point>(); stack.Push(pointseed); bool reachLeft=false, reachRight=false; //2, 执行出栈操作, 然后向上走,直到走到与起始点颜色不同像素或者图片边缘停止 while (stack.Count > 0) { reachLeft = false; reachRight = false; Point point = stack.Pop(); Color pointcolor =bitmap.GetPixel(point.X, point.Y); //跑到最高 while( 1==1) { if (point.Y == 0) break; pointcolor = bitmap.GetPixel(point.X, point.Y-1); if (pointcolor != backgroundColor) break;//向上看看能不能爬 point.Y -= 1; //向上爬一格 } //一直向下跑并填色 while (1 == 1) { //判断左右的像素是否可以入栈 if(point.X > 0 && point.X<bitmap.Width-1) { if(bitmap.GetPixel(point.X - 1, point.Y) == backgroundColor ) { //看看左边的颜色是否为背景色, if (reachLeft == false) { //没有人管,就入栈,并标记已经被管理了 stack.Push(new Point(point.X - 1, point.Y)); reachLeft = true; //表示暂时不需要判断左边是否需要入栈了 } } else { //颜色不一样,已管理的状态打断了,需要复位为false, reachLeft = false; } if (bitmap.GetPixel(point.X + 1, point.Y) == backgroundColor) { //看看右边的颜色是否为背景色, if (reachRight == false) { //没有人管,就入栈,并标记已经被管理了 stack.Push(new Point(point.X + 1, point.Y)); reachRight = true; //表示暂时不需要判断左边是否需要入栈了 } } else { //颜色不一样,已管理的状态打断了,需要复位为false, reachRight = false; } } bitmap.SetPixel(point.X, point.Y, fillcolor); //将当前像素设置为填充色 point.Y++; //将指针向下移动 //判断这一列是否处理完成 if(point.Y>=bitmap.Height-1 || bitmap.GetPixel(point.X,point.Y)!= backgroundColor) { break; //跳出循环 } } } }
还有一些改善的空间,例如边框的颜色对比太死板了,应该有一定的差值, 一定范围内的颜色都可以看成是背景色. 这个很简单,大家就自己实现了.

浙公网安备 33010602011771号