public Bitmap GetProcessedImage(bool useTransparency, out int activePixel) { Bitmap img = OCRImage.Clone(BoundingBox, PixelFormat.Format32bppArgb); activePixel = 0; BitmapData srcData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); IntPtr Scan0 = srcData.Scan0; int stride = srcData.Stride; unsafe { byte *p = (byte *)(void *)Scan0; for (int x = 0; x < img.Width; x++) { for (int y = 0; y < img.Height; y++) { int idx = (y * stride) + x * 4; double s_value = ColorExt.GetSaturation(p[idx + 2], p[idx + 1], p[idx + 0]); byte bval = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); if (s_value >= 80) { p[idx + 0] = 255; p[idx + 1] = 255; p[idx + 2] = 255; p[idx + 3] = (byte)(useTransparency ? 0 : 255); } else { activePixel++; p[idx + 0] = bval; p[idx + 1] = bval; p[idx + 2] = bval; p[idx + 3] = 255; } } } } img.UnlockBits(srcData); return(img); }
public Tuple <Rect2i, Rect2i, Rect2i, int, int> GetCounterArea(Bitmap shot) { BitmapData srcData = shot.LockBits(new Rectangle(0, 0, shot.Width, shot.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr Scan0 = srcData.Scan0; int stride = srcData.Stride; int width = shot.Width; int height = shot.Height; Rect2i resultAll; Rect2i resultNumber; Rect2i resultInner; unsafe { byte *p = (byte *)(void *)Scan0; int topx = width - 1; int topy = height - 1; #region Find Top bool fin = false; for (int x = width - 1; x >= 0 && !fin; x--) { for (int y = 0; y < height && !fin; y++) { int idx = (y * stride) + x * 4; if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { topx = x; topy = y; fin = true; } } } for (int y = topy; y > 0; y--) { int idx = (y * stride) + topx * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { topy = y; } if (hdistance > 50) { break; } } for (int x = topx; x < width; x++) { int idx = (topy * stride) + x * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { topx = x; } if (hdistance > 50) { break; } } #endregion int boty = topy; int botx = topx; #region Find Bottom for (int y = boty; y < height; y++) { int idx = (y * stride) + topx * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { boty = y; } if (hdistance > 50) { break; } } for (int x = topx; x < width; x--) { int idx = (topy * stride) + x * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { botx = x; } if (hdistance > 50) { break; } } #endregion resultAll = new Rect2i(botx, topy, topx - botx, boty - topy); int midy = topy; #region Find Middle bool firstHill = false; for (int y = topy; y < boty; y++) { bool clear = true; for (int x = botx; x < topx; x++) { int idx = (y * stride) + x * 4; clear &= ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16; } firstHill |= !clear; if (firstHill && clear) { midy = y; break; } } #endregion resultNumber = new Rect2i(botx, midy, topx - botx, boty - midy); #region Find Inner Area int minX = topx; int maxX = botx; int minY = boty; int maxY = midy; for (int x = botx; x <= topx; x++) { for (int y = midy; y < boty; y++) { int idx = (y * stride) + x * 4; if (ColorExt.GetSaturation(p[idx + 2], p[idx + 1], p[idx + 0]) < 5) { minX = Math.Min(minX, x); maxX = Math.Max(maxX, x); minY = Math.Min(minY, y); maxY = Math.Max(maxY, y); } } } #endregion resultInner = new Rect2i(minX, minY, maxX - minX + 1, maxY - minY + 1); } shot.UnlockBits(srcData); var ignore_x = MathExt.Min(resultAll.bl.X - 10, resultNumber.bl.X - 10, resultInner.bl.X - 10); var ignore_y = MathExt.Max(resultAll.bl.Y + 10, resultNumber.bl.Y + 10, resultInner.bl.Y + 10); return(Tuple.Create(resultAll, resultNumber, resultInner, ignore_x, ignore_y)); }
public Bitmap GetProcessedImage(bool useTransparency, out int activePixel) { Bitmap img = OCRImage.Clone(GetBoundingBox(), PixelFormat.Format32bppArgb); double hexheight = OCRRadius * (Math.Sin(MathExt.ToRadians(60)) / Math.Sin(MathExt.ToRadians(90))); activePixel = 0; BitmapData srcData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); IntPtr Scan0 = srcData.Scan0; int stride = srcData.Stride; unsafe { byte *p = (byte *)(void *)Scan0; for (int x = 0; x < img.Width; x++) { for (int y = 0; y < img.Height; y++) { int idx = (y * stride) + x * 4; double px = Math.Abs(x - img.Width / 2); double py = Math.Abs(y - img.Height / 2); double pd = Math.Sqrt(px * px + py * py); if (py < hexheight && py + 2 * (px - OCRRadius) < 0) { byte repl_R = 255; byte repl_G = 255; byte repl_B = 255; byte repl_A = (byte)(useTransparency ? 0 : 255); switch (Type) { case HexagonType.HIDDEN: // TRANSPARENT break; case HexagonType.ACTIVE: { double s_value = ColorExt.GetSaturation(p[idx + 2], p[idx + 1], p[idx + 0]); if (s_value >= 80 || pd > (OCRHeight - 1)) { // TRANSPARENT } else { activePixel++; repl_R = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_G = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_B = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_A = 255; } } break; case HexagonType.INACTIVE: { int grayness = (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3; if (grayness < 128 || pd > (OCRHeight - 1)) { // TRANSPARENT } else { activePixel++; repl_R = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_G = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_B = (byte)(255 - (p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_A = 255; } } break; case HexagonType.NOCELL: { double c_distance = ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_CELL_NOCELL); double hsv_value = ColorExt.GetValue(p[idx + 2], p[idx + 1], p[idx + 0]); if (c_distance < 32 || hsv_value > 75) { // TRANSPARENT } else { activePixel++; repl_R = (byte)((p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_G = (byte)((p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_B = (byte)((p[idx + 2] + p[idx + 1] + p[idx + 0]) / 3); repl_A = 255; } } break; default: case HexagonType.UNKNOWN: // TRANSPARENT break; } p[idx + 0] = repl_B; p[idx + 1] = repl_G; p[idx + 2] = repl_R; p[idx + 3] = repl_A; } else { p[idx + 0] = 255; p[idx + 1] = 255; p[idx + 2] = 255; p[idx + 3] = (byte)(useTransparency ? 0 : 255); } } } } img.UnlockBits(srcData); return(img); }