种子漫水填充,但是重复油漆桶的过程中,出现漏填,代码没错

nabasasun 2013-10-24 01:03:52

编译成DEBUG的时候没有问题,关键是Release版本

下面是图片和代码








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

...全文
310 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
nabasasun 2013-10-25
  • 打赏
  • 举报
回复
引用 6 楼 caozhy 的回复:
经验表明,debug能正常,release不正常,一定和指针操作、内存拷贝有关。
我也问过C++的,C++的内存拷贝是下面的 memcpy C#的是 System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
threenewbee 2013-10-24
  • 打赏
  • 举报
回复
引用 5 楼 nabasasun 的回复:
[quote=引用 4 楼 jiaoshiyao 的回复:] 这种东西你必须自己找 能够问的都是技能点 你这个属于不能问的范畴内
那什么东西可以问[/quote] 问当然可以问,你就是问如何能中500万大奖也未尝不可。他的意思是,如果你提问方式不对,回答你问题的人就比较少,回答你问题的针对性也不强,那么你获得满意答案就更费劲。所以提问要注意策略。直接丢出一段代码就显得不太明智。
threenewbee 2013-10-24
  • 打赏
  • 举报
回复
经验表明,debug能正常,release不正常,一定和指针操作、内存拷贝有关。
nabasasun 2013-10-24
  • 打赏
  • 举报
回复
引用 4 楼 jiaoshiyao 的回复:
这种东西你必须自己找 能够问的都是技能点 你这个属于不能问的范畴内
那什么东西可以问
jiaoshiyao 2013-10-24
  • 打赏
  • 举报
回复
这种东西你必须自己找 能够问的都是技能点 你这个属于不能问的范畴内
jiaoshiyao 2013-10-24
  • 打赏
  • 举报
回复
偶也没心情看了!
huwei001982 2013-10-24
  • 打赏
  • 举报
回复
引用 1 楼 wddw1986 的回复:
要有多么大闲心的人会去研究你的代码...
哈哈
cheng2005 2013-10-24
  • 打赏
  • 举报
回复
要有多么大闲心的人会去研究你的代码...
内容概要:本文介绍了一种基于多目标粒子群算法(MOPSO)的微电网优化调度模型,综合考虑风能、光伏、储能系统、柴油发电机、燃气轮机以及与主电网之间的能量交互等多种分布式能源的协同运行。通过构建以运行成本最小化、碳排放最低化和系统可靠性最优化为目标的多目标优化模型,利用Matlab平台实现MOPSO算法求解,完成对微电网在不同运行场景下的能量管理与调度方案优化。该模型能够有效平衡经济性与环保性之间的关系,适用于含多类型分布式电源的复杂微电网系统,具有较强的工程应用价值和科研参考意义; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及工程技术人员,尤其适合从事微电网、智能电网、综合能源系统、可再生能源集成与优化调度等领域研究的专业人士; 使用场景及目标:①用于多能源耦合微电网系统的协同优化调度研究;②支持多目标智能优化算法在能源系统的建模与求解实践,帮助用户掌握MOPSO在实际工程问题的应用方法;③为学术论文复现、毕业设计、科研项目开发提供完整的代码实例与技术支撑; 阅读建议:建议读者结合Matlab代码与理论文档,深入理解目标函数构建、约束条件处理及Pareto最优解集生成机制,重点关注算法参数设置、多目标权衡分析与结果可视化,并可通过调整能源配置或引入新约束进行二次开发与创新研究。

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧