public void ReadLeftSide(RawOutline pathW, bool topDown) { //read once if (_leftSideChecked) { throw new System.NotSupportedException(); } _leftSideChecked = true; if (topDown) { int count = _spanList.Count; RawOutline.BeginLoadSegmentPoints(pathW); for (int i = 0; i < count; ++i) { HSpan span = _spanList[i]; pathW.AppendPoint(span.startX, span.y); } RawOutline.EndLoadSegmentPoints(pathW); } else { RawOutline.BeginLoadSegmentPoints(pathW); for (int i = _spanList.Count - 1; i >= 0; --i) { HSpan span = _spanList[i]; pathW.AppendPoint(span.startX, span.y); } RawOutline.EndLoadSegmentPoints(pathW); } }
HSpan[] SortAndCollectHSpans() { int spanSort(HSpan sp1, HSpan sp2) { //NESTED METHOD //sort asc, if (sp1.y > sp2.y) { return(1); } else if (sp1.y < sp2.y) { return(-1); } else { return(sp1.startX.CompareTo(sp2.startX)); } } //1. _upperSpans.Sort(spanSort); _lowerSpans.Sort(spanSort); HSpan[] hspans = new HSpan[_upperSpans.Count + _lowerSpans.Count]; _upperSpans.CopyTo(hspans); _lowerSpans.CopyTo(hspans, _upperSpans.Count); //clear _upperSpans.Clear(); _lowerSpans.Clear(); return(hspans); }
HSpanColumn FindTouchColumn(HSpan newspan, ref int colIndex) { for (int i = colIndex; i < _hSpanColumns.Length; ++i) { HSpanColumn col = _hSpanColumns[i]; if (col.BottomSideTouchWith(newspan.y, newspan.startX, newspan.endX)) { //found colIndex = i; return(col); } } //---- if (colIndex > 0) { //we didn't start from the first for (int i = 0; i < colIndex; ++i) { HSpanColumn col = _hSpanColumns[i]; if (col.BottomSideTouchWith(newspan.y, newspan.startX, newspan.endX)) { //found colIndex = i; return(col); } } } //not found return(null); }
public void AddHSpan(HSpan span) { _spanList.Add(span); XLeftBottom = span.startX; XRightBottom = span.endX; YBottom = span.y + 1; }
void AddHSpan(HSpan hspan) { if (hspan.y >= _yCutAt) { _lowerSpans.Add(hspan); } else { _upperSpans.Add(hspan); } }
public HSpan[] InternalFill(IPixelEvaluator pixelEvalutor, int x, int y, bool collectHSpans) { _pixelEvalutor = pixelEvalutor; _yCutAt = y; //set cut-point if (collectHSpans) { _upperSpans.Clear(); _lowerSpans.Clear(); } int imgW = pixelEvalutor.OrgBitmapWidth; int imgH = pixelEvalutor.OrgBitmapHeight; //reset new buffer, clear mem? _pixelsChecked = new bool[imgW * imgH]; //*** pixelEvalutor.SetStartPos(x, y); TryLinearFill(x, y); while (_hspanQueue.Count > 0) { HSpan hspan = _hspanQueue.Dequeue(); if (collectHSpans) { AddHSpan(hspan); } int downY = hspan.y - 1; int upY = hspan.y + 1; int downPixelOffset = (imgW * (hspan.y - 1)) + hspan.startX; int upPixelOffset = (imgW * (hspan.y + 1)) + hspan.startX; for (int rangeX = hspan.startX; rangeX < hspan.endX; rangeX++) { if (hspan.y > 0 && !_pixelsChecked[downPixelOffset]) { TryLinearFill(rangeX, downY); } if (hspan.y < (imgH - 1) && !_pixelsChecked[upPixelOffset]) { TryLinearFill(rangeX, upY); } upPixelOffset++; downPixelOffset++; } } //reset _hspanQueue.Clear(); _pixelEvalutor = null; return(collectHSpans ? SortAndCollectHSpans() : null); }
/// <summary> /// check if the bottom side of this group touch with specific range /// </summary> /// <param name="lowerGroupTopLeft"></param> /// <param name="lowerGroupTopRight"></param> /// <returns></returns> public bool BottomSideTouchWith(int lowerGroupTop, int lowerGroupTopLeft, int lowerGroupTopRight) { //[ THIS group ] //--------------------- //[ other (lower)group] return((lowerGroupTop != this.YBottom) ? false : HSpan.HorizontalTouchWith( XLeftBottom, XRightBottom, lowerGroupTopLeft, lowerGroupTopRight)); }
public void Separate(HSpan[] hspans) { int count = hspans.Length; if (count == 0) { return; } int startCollectIndex = 0; int colCount = 0; _lastestLine = hspans[0].y; for (int i = 0; i < count; ++i) { HSpan sp = hspans[i]; int lineDiff = sp.y - _lastestLine; switch (lineDiff) { case 1: { //go next lower line //flush current collected columns FlushCollectedColumns(hspans, startCollectIndex, colCount); // startCollectIndex = i; colCount = 1; _lastestLine = sp.y; } break; case 0: { //sameline colCount++; } break; default: throw new System.NotSupportedException(); } } if (startCollectIndex < count - 1) { //flush remaining FlushCollectedColumns(hspans, startCollectIndex, colCount); } }
/// <summary> /// check if the top side of this group touch with specific range) /// </summary> /// <param name="upperBottomLeft"></param> /// <param name="upperBottomRight"></param> /// <returns></returns> public bool TopSideTouchWith(int upperBottom, int upperBottomLeft, int upperBottomRight) { //[ other (lower)group] //--------------------- //[ THIS group ] //find the first column that its top side touch with //another uppper group return((upperBottom != this.YTop) ? false : HSpan.HorizontalTouchWith( XLeftTop, XRightTop, upperBottomLeft, upperBottomRight)); }
PixelFarm.Drawing.Rectangle FindTotalRectBoundsFromHSpans() { HSpan[] hspans = HSpans; if (hspans == null) { throw new System.NotSupportedException(); } int left = int.MaxValue; int right = int.MinValue; int top = int.MaxValue; int bottom = int.MinValue; for (int i = 0; i < hspans.Length; ++i) { HSpan span = hspans[i]; int sp_bottom = span.y + 1; if (sp_bottom > bottom) { bottom = sp_bottom; } if (span.y < top) { top = span.y; } // if (span.startX < left) { left = span.startX; } if (span.endX > right) { right = span.endX; } } return(new Drawing.Rectangle(left, top, right - left, bottom - top)); }
public bool AddHSpans(HSpan[] hspans, int startIndex, int count) { int index = startIndex; //we must ... //1. touch one by one //and 2. no overlaped column for (int i = 0; i < _hSpanColumns.Length; ++i) { HSpanColumn col = _hSpanColumns[i]; HSpan hspan = hspans[index]; if (!col.BottomSideTouchWith(hspan.y, hspan.startX, hspan.endX)) { //found some 'untouch column' //break all //need another vertical group return(false); } else if (i > 0 && _hSpanColumns[i - 1].BottomSideTouchWith(hspan.y, hspan.startX, hspan.endX)) { //see Test/Data/lion_1_v3_2.png for example //check if current hspan dose not touch with prev column //in this case => start a new column return(false); } index++; } //--- //pass all index = startIndex; //reset for (int i = 0; i < _hSpanColumns.Length; ++i) { HSpanColumn col = _hSpanColumns[i]; col.AddHSpan(hspans[index]); index++; } return(true); }
public void EvaluateCorners() { #if DEBUG dbugEvalCorners = true; #endif //the column may not be rectangle shape *** if (_spanList.Count == 0) { //?? throw new System.NotSupportedException(); } //.. HSpan hspan = _spanList[0]; XLeftTop = hspan.startX; XRightTop = hspan.endX; YTop = hspan.y; hspan = _spanList[_spanList.Count - 1]; XLeftBottom = hspan.startX; XRightBottom = hspan.endX; YBottom = hspan.y + 1;//*** }
public static CpuBlit.MemBitmap CreateMaskBitmap(this ReconstructedRegionData rgnData, Drawing.Color solidPartColor, Drawing.Color holeColor, bool useFitBounds = true) { //1. find size of membitmap Drawing.Rectangle fitBounds = rgnData.GetBounds(); //2. fit bounds or not int bmpW, bmpH, offsetX, offsetY; if (useFitBounds) { bmpW = fitBounds.Width; bmpH = fitBounds.Height; offsetX = -fitBounds.X; offsetY = -fitBounds.Y; } else { bmpW = fitBounds.Left + fitBounds.Right; bmpH = fitBounds.Top + fitBounds.Height; offsetX = 0; offsetY = 0; } //3. create mask bmp MemBitmap maskBmp = new MemBitmap(bmpW, bmpH); //4. fill mask data maskBmp.Clear(solidPartColor); int holdColorInt32 = (holeColor.A << CO.A_SHIFT) | (holeColor.B << CO.B_SHIFT) | (holeColor.G << CO.G_SHIFT) | (holeColor.R << CO.R_SHIFT); var memPtr = MemBitmap.GetBufferPtr(maskBmp); unsafe { int *buffer = (int *)memPtr.Ptr; //fill HSpan[] hspans = rgnData.HSpans; if (useFitBounds) { int totalBufferLen = bmpW * bmpH; for (int i = 0; i < hspans.Length; ++i) { HSpan span = hspans[i]; int len = span.endX - span.startX; #if DEBUG int offset = ((span.y + offsetY) * bmpW + (span.startX + offsetX)); if (offset >= totalBufferLen || offset + len > totalBufferLen) { throw new System.Exception("out-of-range"); break; } else if (offset < 0 || offset + len < 0) { } #endif int *pixAddr = buffer + ((span.y + offsetY) * bmpW + (span.startX + offsetX)); //with offsetX,offsetY for (int n = len - 1; n >= 0; --n) { *pixAddr = holdColorInt32; pixAddr++; } } } else { for (int i = 0; i < hspans.Length; ++i) { HSpan span = hspans[i]; int len = span.endX - span.startX; int *pixAddr = buffer + ((span.y) * bmpW + (span.startX)); //no offsetX,offsetY for (int n = len - 1; n >= 0; --n) { *pixAddr = holdColorInt32; pixAddr++; } } } } //return null; return(maskBmp); }