private unsafe void DoMagicWand(BitmapData pdata, Point startPoint, byte tolerance, bool isContinued, Action <int, int, int> segmentAction, Action regionAction) { CheckArgBandFillFields(pdata, tolerance, startPoint); _visitedPixels = new StatusRecorder(_width * pdata.Height); if (isContinued) { _seeds.Enqueue(startPoint.Y * _width + startPoint.X); FloodFill(segmentAction); if (regionAction != null) { regionAction(); } } else { int count = _width * _height; byte *ptr; for (int i = 0; i < count; i++) { if (_visitedPixels.IsTrue(i)) { continue; } ptr = (byte *)_scan0 + (i / _width) * _stride + (i % _width) * _pixelWidth; if (ColorIsMatched(ptr)) { _seeds.Enqueue(i); FloodFill(segmentAction); if (regionAction != null) { regionAction(); } } else { _visitedPixels.SetStatus(i, true); } } } }
public static int[] Reversal(int[] aoi, Size size) { int count = size.Width * size.Height; StatusRecorder status = new StatusRecorder(count); int aoiCount = aoi.Length; for (int i = 0; i < aoiCount; i++) { status.SetStatus(aoi[i], true); } List <int> retAOI = new List <int>(count - aoiCount); for (int i = 0; i < count; i++) { if (!status.IsTrue(i)) { retAOI.Add(i); } } return(retAOI.Count > 0 ? retAOI.ToArray() : null); }
private unsafe void FloodFill(Action <int, int, int> segmentAction) { int oRow = 0; int oCol = 0; byte *ptr0 = (byte *)_scan0; byte *oPtr = ptr0; byte *ptr; int bCol = 0, eCol = 0; int seedIdx = 0; while (_seeds.Count > 0) { int oSeedIdx = _seeds.Dequeue(); if (_visitedPixels.IsTrue(oSeedIdx)) { continue; } oRow = oSeedIdx / _width; oCol = oSeedIdx % _width; oPtr = ptr0 + oRow * _stride + oCol * _pixelWidth; //临界像元标记 bool isCriticalPixel = true; bool isEnd = false; //—> left bCol = oCol; if (oCol > 0) { ptr = oPtr; seedIdx = oSeedIdx; Dec(ref bCol, ref ptr, ref seedIdx); isEnd = IsToLeftBorder(ptr, bCol); while (!isEnd) { HitPixel(seedIdx, ptr); Dec(ref bCol, ref ptr, ref seedIdx); isEnd = IsToLeftBorder(ptr, bCol); isCriticalPixel = false; } Inc(ref bCol, ref ptr, ref seedIdx); if (isCriticalPixel) { HitPixel(seedIdx, ptr); } //for debug //if (bCol > 0) // HitColorGreen(ptr - _pixelWidth); } //—> right eCol = oCol; if (oCol < _width - 1) { isCriticalPixel = true; ptr = oPtr; seedIdx = oSeedIdx; Inc(ref eCol, ref ptr, ref seedIdx); isEnd = IsToRightBorder(ptr, eCol); while (!isEnd) { HitPixel(seedIdx, ptr); Inc(ref eCol, ref ptr, ref seedIdx); isEnd = IsToRightBorder(ptr, eCol); isCriticalPixel = false; } Dec(ref eCol, ref ptr, ref seedIdx); if (isCriticalPixel) { HitPixel(seedIdx, ptr); } //for debug //if (eCol < _width - 1) // HitColorGreen(ptr + _pixelWidth); } // HitPixel(oSeedIdx, oPtr); // if (segmentAction != null) { segmentAction(oRow, bCol, eCol); } //—> up if (oRow > 0) { UpDownMoveRow(bCol, eCol, oRow, -1, ptr0); } //—> down if (oRow < _height - 1) { UpDownMoveRow(bCol, eCol, oRow, 1, ptr0); } // if (!_visitedPixels.IsTrue(oSeedIdx)) { _visitedPixels.SetStatus(oSeedIdx, true); } } }