protected virtual void ExcuteFloodFill(BitMap2d data, Int16Double seed) { this.bmp = data; data.ResetVisitCount(); flagsMap = new FlagMap2d(data.width, data.height); Int16Double[] adjPoints4 = new Int16Double[4]; flagsMap.SetFlagOn(seed.X, seed.Y, true); container.Push(seed); Process(seed); while (!container.Empty()) { Int16Double p = container.Pop(); InitAdj4(ref adjPoints4, ref p); for (int adjIndex = 0; adjIndex < 4; adjIndex++) { Int16Double t = adjPoints4[adjIndex]; if (t.X < data.width && t.X >= 0 && t.Y < data.height && t.Y >= 0) { if (!flagsMap.GetFlagOn(t.X, t.Y) && IncludePredicate(t)) { flagsMap.SetFlagOn(t.X, t.Y, true); container.Push(t); Process(t); } } } } return; }
private int FindYRight(int y, int x) { int yright = y + 1; while (true) { if (yright == bmp.height || flagsMap.GetFlagOn(x, yright)) { break; } else { if (IncludePredicate(x, yright)) { Int16Double t = new Int16Double(x, yright); flagsMap.SetFlagOn(x, yright, true); Process(t); yright++; } else { break; } } } return(yright - 1); }
private int FindYLeft(int y, int x) { int yleft = y - 1; while (true) { if (yleft == -1 || flagsMap.GetFlagOn(x, yleft)) { break; } else { if (IncludePredicate(x, yleft)) { Int16Double t = new Int16Double(x, yleft); flagsMap.SetFlagOn(x, yleft, true); Process(t); yleft--; } else { break; } } } return(yleft + 1); }
protected int FindXLeft(int x, int y) { int xleft = x - 1; while (true) { if (xleft == -1 || flagsMap.GetFlagOn(xleft, y)) { break; } else { if (IncludePredicate(xleft, y)) { Int16Double t = new Int16Double(xleft, y); flagsMap.SetFlagOn(xleft, y, true); Process(t); xleft--; } else { break; } } } return(xleft + 1); }
}//区段法的CheckRange 注意与扫描线的CheckRange的不同 protected int FindXRight(int x, int y) { int xright = x + 1; while (true) { if (xright == bmp.width || flagsMap.GetFlagOn(xright, y)) { break; } else { if (IncludePredicate(xright, y)) { Int16Double t = new Int16Double(xright, y); flagsMap.SetFlagOn(xright, y, true); Process(t); xright++; } else { break; } } } return(xright - 1); }
}//FindXLeft操作 protected int FindXRight(Int16Double p) { int xright = p.X + 1; while (true) { if (xright == bmp.width || flagsMap.GetFlagOn(xright, p.Y)) { break; } else { byte value = bmp.GetPixel(xright, p.Y); if (IncludePredicate(xright, p.Y)) { Int16Double t = new Int16Double(xright, p.Y); flagsMap.SetFlagOn(xright, p.Y, true); Process(t); xright++; } else { break; } } } return(xright - 1); }//FindXRight操作
}//CheckRange操作 protected int FindXLeft(Int16Double p) { int xleft = p.X - 1; while (true) { if (xleft == -1 || flagsMap.GetFlagOn(xleft, p.Y)) { break; } else { byte value = bmp.GetPixel(xleft, p.Y); if (IncludePredicate(xleft, p.Y)) { Int16Double t = new Int16Double(xleft, p.Y); flagsMap.SetFlagOn(xleft, p.Y, true); Process(t); xleft--; } else { break; } } } return(xleft + 1); }//FindXLeft操作
static void TestFloodFill(BitMap2d bmp, Int16Double seed) { { FloodFill2d_T ff = new FloodFill2d_T(); ff.ExcuteFloodFill_Stack(bmp, seed); ff.report.PrintInfo(); } { FloodFill2d_T ff = new FloodFill2d_T(); ff.ExcuteFloodFill_Queue(bmp, seed); ff.report.PrintInfo(); } }
static void TestScanlineFill(BitMap2d bmp, Int16Double seed) { { ScanlineFill2d_T ff = new ScanlineFill2d_T(); ff.ExcuteScanlineFill_Stack(bmp, seed); ff.report.PrintInfo(); } { ScanlineFill2d_T ff = new ScanlineFill2d_T(); ff.ExcuteScanlineFill_Queue(bmp, seed); ff.report.PrintInfo(); } }
static void TestSpanFill(BitMap2d bmp, Int16Double seed) { { SpanFill2d_T ff2 = new SpanFill2d_T(); ff2.ExcuteSpanFill_Stack(bmp, seed); ff2.report.PrintInfo(); } { SpanFill2d_T ff2 = new SpanFill2d_T(); ff2.ExcuteSpanFill_Queue(bmp, seed); ff2.report.PrintInfo(); //ff2.report.OutPutMap(ff2.flagsMap, "result.bmp"); } }
protected void InitAdj4(ref Int16Double[] adjPoints4, ref Int16Double p) { adjPoints4[0].X = p.X - 1; adjPoints4[0].Y = p.Y; adjPoints4[1].X = p.X + 1; adjPoints4[1].Y = p.Y; adjPoints4[2].X = p.X; adjPoints4[2].Y = p.Y - 1; adjPoints4[3].X = p.X; adjPoints4[3].Y = p.Y + 1; }
public override void ExcuteSpanFill_S(BitMap2d data, Int16Double seed) { watch.Start(); base.ExcuteSpanFill_S(data, seed); watch.Stop(); report.time = watch.ElapsedMilliseconds; report.result_point_count = count; report.bmp_get_count = data.action_get_count; report.bmp_set_count = data.action_set_count; report.container_pop_count = queue.action_pop_count; report.container_push_count = queue.action_push_count; report.container_max_size = queue.max_contain_count; report.flag_get_count = flagsMap.action_get_count; report.flag_set_count = flagsMap.action_set_count; return; }
public void ExcuteFloodFill_Stack(BitMap2d data, Int16Double seed) { watch.Start(); container = new Container_Stack <Int16Double>(); base.ExcuteFloodFill(data, seed); watch.Stop(); report.time = watch.ElapsedMilliseconds; report.result_point_count = count; report.bmp_get_count = data.action_get_count; report.bmp_set_count = data.action_set_count; report.container_pop_count = container.action_pop_count; report.container_push_count = container.action_push_count; report.container_max_size = container.max_contain_count; report.flag_get_count = flagsMap.action_get_count; report.flag_set_count = flagsMap.action_set_count; return; }
protected virtual void ExcuteScanlineFill(BitMap2d data, Int16Double seed) { this.bmp = data; data.ResetVisitCount(); flagsMap = new FlagMap2d(data.width, data.height); flagsMap.SetFlagOn(seed.X, seed.Y, true); container.Push(seed); Process(seed); while (!container.Empty()) { Int16Double p = container.Pop(); int xleft = FindXLeft(p); int xright = FindXRight(p); if (p.Y - 1 >= 0) { CheckRange(xleft, xright, p.Y - 1); } if (p.Y + 1 < data.height) { CheckRange(xleft, xright, p.Y + 1); } } }//该函数为扫描线法主体
}//该函数为扫描线法主体 protected void CheckRange(int xleft, int xright, int y) { for (int i = xleft; i <= xright;) { if ((!flagsMap.GetFlagOn(i, y)) && IncludePredicate(i, y)) { int rb = i + 1; while (rb <= xright && (!flagsMap.GetFlagOn(rb, y)) && IncludePredicate(rb, y)) { rb++; } rb--; Int16Double t = new Int16Double(rb, y); flagsMap.SetFlagOn(rb, y, true); container.Push(t); Process(t); i = rb + 1; } else { i++; } } }//CheckRange操作
public void Process(Int16Double p) { count++; }
protected Container <Span> container;//以Span为单位的Queue或Stack容器 protected virtual void ExcuteSpanFill(BitMap2d data, Int16Double seed) { this.bmp = data; data.ResetVisitCount(); flagsMap = new FlagMap2d(data.width, data.height); Process(seed); flagsMap.SetFlagOn(seed.X, seed.Y, true); Span seedspan = new Span(); seedspan.XLeft = seed.X; seedspan.XRight = seed.X; seedspan.Y = seed.Y; seedspan.ParentDirection = ParentDirections.Non; seedspan.Extended = ExtendTypes.UnRez; container.Push(seedspan); while (!container.Empty()) { Span span = container.Pop(); #region AllRez if (span.Extended == ExtendTypes.AllRez) { if (span.ParentDirection == ParentDirections.Y2) { if (span.Y - 1 >= 0) { CheckRange(span.XLeft, span.XRight, span.Y - 1, ParentDirections.Y2); } continue; } if (span.ParentDirection == ParentDirections.Y0) { if (span.Y + 1 < bmp.height) { CheckRange(span.XLeft, span.XRight, span.Y + 1, ParentDirections.Y0); } continue; } throw new Exception(); } #endregion #region UnRez if (span.Extended == ExtendTypes.UnRez) { int xl = FindXLeft(span.XLeft, span.Y); int xr = FindXRight(span.XRight, span.Y); if (span.ParentDirection == ParentDirections.Y2) { if (span.Y - 1 >= 0) { CheckRange(xl, xr, span.Y - 1, ParentDirections.Y2); } if (span.Y + 1 < bmp.height) { if (xl != span.XLeft) { CheckRange(xl, span.XLeft, span.Y + 1, ParentDirections.Y0); } if (span.XRight != xr) { CheckRange(span.XRight, xr, span.Y + 1, ParentDirections.Y0); } } continue; } if (span.ParentDirection == ParentDirections.Y0) { if (span.Y + 1 < bmp.height) { CheckRange(xl, xr, span.Y + 1, ParentDirections.Y0); } if (span.Y - 1 >= 0) { if (xl != span.XLeft) { CheckRange(xl, span.XLeft, span.Y - 1, ParentDirections.Y2); } if (span.XRight != xr) { CheckRange(span.XRight, xr, span.Y - 1, ParentDirections.Y2); } } continue; } if (span.ParentDirection == ParentDirections.Non) { if (span.Y + 1 < bmp.height) { CheckRange(xl, xr, span.Y + 1, ParentDirections.Y0); } if (span.Y - 1 >= 0) { CheckRange(xl, xr, span.Y - 1, ParentDirections.Y2); } continue; } throw new Exception(); } #endregion #region LeftRequired if (span.Extended == ExtendTypes.LeftRequired) { int xl = FindXLeft(span.XLeft, span.Y); if (span.ParentDirection == ParentDirections.Y2) { if (span.Y - 1 >= 0) { CheckRange(xl, span.XRight, span.Y - 1, ParentDirections.Y2); } if (span.Y + 1 < bmp.height && xl != span.XLeft) { CheckRange(xl, span.XLeft, span.Y + 1, ParentDirections.Y0); } continue; } if (span.ParentDirection == ParentDirections.Y0) { if (span.Y + 1 < bmp.height) { CheckRange(xl, span.XRight, span.Y + 1, ParentDirections.Y0); } if (span.Y - 1 >= 0 && xl != span.XLeft) { CheckRange(xl, span.XLeft, span.Y - 1, ParentDirections.Y2); } continue; } throw new Exception(); } #endregion #region RightRequired if (span.Extended == ExtendTypes.RightRequired) { int xr = FindXRight(span.XRight, span.Y); if (span.ParentDirection == ParentDirections.Y2) { if (span.Y - 1 >= 0) { CheckRange(span.XLeft, xr, span.Y - 1, ParentDirections.Y2); } if (span.Y + 1 < bmp.height && span.XRight != xr) { CheckRange(span.XRight, xr, span.Y + 1, ParentDirections.Y0); } continue; } if (span.ParentDirection == ParentDirections.Y0) { if (span.Y + 1 < bmp.height) { CheckRange(span.XLeft, xr, span.Y + 1, ParentDirections.Y0); } if (span.Y - 1 >= 0 && span.XRight != xr) { CheckRange(span.XRight, xr, span.Y - 1, ParentDirections.Y2); } continue; } throw new Exception(); } #endregion } }
public virtual void ExcuteSpanFill_S(BitMap2d data, Int16Double seed) { this.bmp = data; data.ResetVisitCount(); flagsMap = new FlagMap2d(data.width, data.height); queue = new Container_Stack <SpanY>(); Process(seed); flagsMap.SetFlagOn(seed.X, seed.Y, true); SpanY seedspan = new SpanY(); seedspan.YLeft = seed.Y; seedspan.YRight = seed.Y; seedspan.X = seed.X; seedspan.ParentDirection = ParentDirectionsY.Non; seedspan.Extended = ExtendTypesY.UnRez; queue.Push(seedspan); while (!queue.Empty()) { SpanY span = queue.Pop(); #region AllRez if (span.Extended == ExtendTypesY.AllRez) { if (span.ParentDirection == ParentDirectionsY.X2) { if (span.X - 1 >= 0) { CheckRange(span.YLeft, span.YRight, span.X - 1, ParentDirectionsY.X2); } continue; } if (span.ParentDirection == ParentDirectionsY.X0) { if (span.X + 1 < bmp.width) { CheckRange(span.YLeft, span.YRight, span.X + 1, ParentDirectionsY.X0); } continue; } throw new Exception(); } #endregion #region UnRez if (span.Extended == ExtendTypesY.UnRez) { int yl = FindYLeft(span.YLeft, span.X); int yr = FindYRight(span.YRight, span.X); if (span.ParentDirection == ParentDirectionsY.X2) { if (span.X - 1 >= 0) { CheckRange(yl, yr, span.X - 1, ParentDirectionsY.X2); } if (span.X + 1 < bmp.width) { if (yl != span.YLeft) { CheckRange(yl, span.YLeft, span.X + 1, ParentDirectionsY.X0); } if (span.YRight != yr) { CheckRange(span.YRight, yr, span.X + 1, ParentDirectionsY.X0); } } continue; } if (span.ParentDirection == ParentDirectionsY.X0) { if (span.X + 1 < bmp.width) { CheckRange(yl, yr, span.X + 1, ParentDirectionsY.X0); } if (span.X - 1 >= 0) { if (yl != span.YLeft) { CheckRange(yl, span.YLeft, span.X - 1, ParentDirectionsY.X2); } if (span.YRight != yr) { CheckRange(span.YRight, yr, span.X - 1, ParentDirectionsY.X2); } } continue; } if (span.ParentDirection == ParentDirectionsY.Non) { if (span.X + 1 < bmp.width) { CheckRange(yl, yr, span.X + 1, ParentDirectionsY.X0); } if (span.X - 1 >= 0) { CheckRange(yl, yr, span.X - 1, ParentDirectionsY.X2); } continue; } throw new Exception(); } #endregion #region LeftRequired if (span.Extended == ExtendTypesY.LeftRequired) { int yl = FindYLeft(span.YLeft, span.X); if (span.ParentDirection == ParentDirectionsY.X2) { if (span.X - 1 >= 0) { CheckRange(yl, span.YRight, span.X - 1, ParentDirectionsY.X2); } if (span.X + 1 < bmp.width && yl != span.YLeft) { CheckRange(yl, span.YLeft, span.X + 1, ParentDirectionsY.X0); } continue; } if (span.ParentDirection == ParentDirectionsY.X0) { if (span.X + 1 < bmp.width) { CheckRange(yl, span.YRight, span.X + 1, ParentDirectionsY.X0); } if (span.X - 1 >= 0 && yl != span.YLeft) { CheckRange(yl, span.YLeft, span.X - 1, ParentDirectionsY.X2); } continue; } throw new Exception(); } #endregion #region RightRequired if (span.Extended == ExtendTypesY.RightRequired) { int yr = FindYRight(span.YRight, span.X); if (span.ParentDirection == ParentDirectionsY.X2) { if (span.X - 1 >= 0) { CheckRange(span.YLeft, yr, span.X - 1, ParentDirectionsY.X2); } if (span.X + 1 < bmp.width && span.YRight != yr) { CheckRange(span.YRight, yr, span.X + 1, ParentDirectionsY.X0); } continue; } if (span.ParentDirection == ParentDirectionsY.X0) { if (span.X + 1 < bmp.width) { CheckRange(span.YLeft, yr, span.X + 1, ParentDirectionsY.X0); } if (span.X - 1 >= 0 && span.YRight != yr) { CheckRange(span.YRight, yr, span.X - 1, ParentDirectionsY.X2); } continue; } throw new Exception(); } #endregion } }
protected void Process(Int16Double p) { count++; return; }
protected bool IncludePredicate(Int16Double p) { return(bmp.GetPixel(p.X, p.Y) == BitMap2d.WHITE); }