BitmapBasedRegion CreateNewRegion(BitmapBasedRegion another, SetOperationName opName) { // MemBitmap myBmp = this.GetRegionBitmap(); //or create new as need MemBitmap anotherBmp = another.GetRegionBitmap(); //do bitmap union //2 rgn merge may Rectangle r1Rect = this.GetRectBounds(); Rectangle r2Rect = another.GetRectBounds(); Rectangle r3Rect = Rectangle.Union(r1Rect, r2Rect); // MemBitmap r3Bmp = new MemBitmap(r3Rect.Width, r3Rect.Height); r3Bmp.Clear(Color.Black); MaskBitmapReader r1 = new MaskBitmapReader(); r1.SetBitmap(myBmp); MaskBitmapReader r2 = new MaskBitmapReader(); r2.SetBitmap(anotherBmp); MaskBitmapWriter w3 = new MaskBitmapWriter(); w3.SetBitmap(r3Bmp); int height = r3Rect.Height; int width = r3Rect.Width; switch (opName) { case SetOperationName.Union: for (int y = 0; y < height; ++y) { r1.MoveTo(0, y); r2.MoveTo(0, y); w3.MoveTo(0, y); for (int x = 0; x < width; ++x) { w3.Union(r1.Read(), r2.Read()); r1.MoveRight(); r2.MoveRight(); w3.MoveRight(); } } break; case SetOperationName.Intersect: for (int y = 0; y < height; ++y) { r1.MoveTo(0, y); r2.MoveTo(0, y); w3.MoveTo(0, y); for (int x = 0; x < width; ++x) { w3.Intersect(r1.Read(), r2.Read()); r1.MoveRight(); r2.MoveRight(); w3.MoveRight(); } } break; case SetOperationName.Diff: for (int y = 0; y < height; ++y) { r1.MoveTo(0, y); r2.MoveTo(0, y); w3.MoveTo(0, y); for (int x = 0; x < width; ++x) { w3.Diff(r1.Read(), r2.Read()); r1.MoveRight(); r2.MoveRight(); w3.MoveRight(); } } break; case SetOperationName.Xor: for (int y = 0; y < height; ++y) { r1.MoveTo(0, y); r2.MoveTo(0, y); w3.MoveTo(0, y); for (int x = 0; x < width; ++x) { w3.Xor(r1.Read(), r2.Read()); r1.MoveRight(); r2.MoveRight(); w3.MoveRight(); } } break; } return(new BitmapBasedRegion(r3Bmp)); }
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); }