protected void DrawRectangle(FastBitmapHSV bitmap, int posX, int posY, int width, int height, byte color, int border = 1) { FastPixelHSV pixelOb = new FastPixelHSV(color, color, color); for (int idxX = 0; idxX < width; idxX++) { bitmap.SetPixel(posX + idxX, posY - border, pixelOb); bitmap.SetPixel(posX + idxX, posY + height + border, pixelOb); } for (int idxY = 0; idxY < height; idxY++) { bitmap.SetPixel(posX - border, posY + idxY, pixelOb); bitmap.SetPixel(posX + width + border, posY + idxY, pixelOb); } }
protected void ScanActionSlot(FastBitmapHSV bitmap, Point slotPos, ScreenData screenData, int slotIdx) { float[] pixelInput = ExtractActionSlotData(bitmap, slotIdx); ESlotType SlotType = (ESlotType)classifierPurify.Calculate(pixelInput, out float BestPct); screenData.Slots[slotIdx] = SlotType; if (DebugLevel >= EDebugLevel.Simple) { Console.WriteLine("{0} ScanActionSlot[{1}]: {2} ({3:P2})", ScannerName, slotIdx, screenData.Slots[slotIdx], BestPct); } if (DebugLevel >= EDebugLevel.Verbose) { byte frameColor = (SlotType == ESlotType.None) ? (byte)0 : (SlotType == ESlotType.Locked || SlotType == ESlotType.LockedBig) ? (byte)128 : (byte)255; DrawRectangle(bitmap, slotPos.X, slotPos.Y, 48, 96, frameColor, 1); if (SlotType == ESlotType.Big) { DrawRectangle(bitmap, slotPos.X, slotPos.Y, 48, 96, frameColor, 3); } int previewX = slotPos.X + ((slotIdx < 4) ? -20 : (48 + 5)); int previewY = slotPos.Y; int readIdx = 0; for (int idxY = 0; idxY < 16; idxY++) { for (int idxX = 0; idxX < 16; idxX++) { byte color = (byte)(pixelInput[readIdx] * 255); readIdx++; bitmap.SetPixel(previewX + idxX, previewY + idxY, new FastPixelHSV(color, color, color)); } } } }
public static bool CreateFloodFillBitmap(FastBitmapHSV srcBitmap, Point floodOrigin, Size floodExtent, FastPixelMatch colorMatch, out FastBitmapHSV floodBitmap, out Rectangle floodBounds, bool bDebugMode = false) { List <Point> floodPoints = new List <Point>(); int minX = floodOrigin.X; int maxX = floodOrigin.X; int minY = floodOrigin.Y; int maxY = floodOrigin.Y; Rectangle boundRect = new Rectangle(floodOrigin.X - floodExtent.Width, floodOrigin.Y - floodExtent.Height, floodExtent.Width * 2, floodExtent.Height * 2); Stack <Point> openList = new Stack <Point>(); openList.Push(floodOrigin); while (openList.Count > 0) { Point testPoint = openList.Pop(); if (floodPoints.Contains(testPoint)) { continue; } FastPixelHSV testPx = srcBitmap.GetPixel(testPoint.X, testPoint.Y); if (bDebugMode) { Console.WriteLine("[" + testPoint.X + ", " + testPoint.Y + "] " + testPx + ", match:" + colorMatch.IsMatching(testPx) + ", inBounds:" + boundRect.Contains(testPoint)); } if (colorMatch.IsMatching(testPx) && boundRect.Contains(testPoint)) { floodPoints.Add(testPoint); minX = Math.Min(minX, testPoint.X); maxX = Math.Max(maxX, testPoint.X); minY = Math.Min(minY, testPoint.Y); maxY = Math.Max(maxY, testPoint.Y); openList.Push(new Point(testPoint.X - 1, testPoint.Y)); openList.Push(new Point(testPoint.X + 1, testPoint.Y)); openList.Push(new Point(testPoint.X, testPoint.Y - 1)); openList.Push(new Point(testPoint.X, testPoint.Y + 1)); openList.Push(new Point(testPoint.X - 1, testPoint.Y - 1)); openList.Push(new Point(testPoint.X + 1, testPoint.Y - 1)); openList.Push(new Point(testPoint.X - 1, testPoint.Y + 1)); openList.Push(new Point(testPoint.X + 1, testPoint.Y + 1)); } } floodBounds = new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1); if (floodPoints.Count > 0) { floodBitmap = new FastBitmapHSV(floodBounds.Width, floodBounds.Height); int numPx = floodBounds.Width * floodBounds.Height; for (int Idx = 0; Idx < numPx; Idx++) { floodBitmap.SetPixel(Idx, new FastPixelHSV(false)); } foreach (Point p in floodPoints) { int Idx = (p.X - minX) + ((p.Y - minY) * floodBounds.Width); floodBitmap.SetPixel(Idx, new FastPixelHSV(true)); } } else { floodBitmap = null; } return(floodBitmap != null); }