using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; namespace GummingCommon { public class ImageDetectService { public static List QueryRects(Bitmap srcBitmap, Color color, Color fillColor) { List rects = new List(); Point pt = QueryFirstPoint(srcBitmap, color); while (pt.X > 0 || pt.Y > 0) { Rectangle rect = FloodFill(srcBitmap, pt, color, fillColor); pt = QueryFirstPoint(srcBitmap, color); if (rect.Width > 10 || rect.Height > 10) { rects.Add(rect); } } return rects; } public static void FillRedPoint(Bitmap bmp) { System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = bmpData.Stride * bmp.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int _Index = 0; for (int z = 0; z != bmp.Height; z++) { _Index = z * bmpData.Stride; for (int i = 0; i != bmp.Width; i++) { byte b = grayValues[_Index]; byte g = grayValues[_Index + 1]; byte r = grayValues[_Index + 2]; if (b != 5 && g != 5 && r != 5) { grayValues[_Index] = 0; grayValues[_Index + 1] = 0; grayValues[_Index + 2] = 255; } else { grayValues[_Index] = 255; grayValues[_Index + 1] = 255; grayValues[_Index + 2] = 255; } _Index += 3; } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); bmp.UnlockBits(bmpData); } public static void FillWhiteToSpecialPoint(Bitmap bmp, byte rin, byte gin, byte bin) { System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = bmpData.Stride * bmp.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int _Index = 0; for (int z = 0; z != bmp.Height; z++) { _Index = z * bmpData.Stride; for (int i = 0; i != bmp.Width; i++) { byte b = grayValues[_Index]; byte g = grayValues[_Index + 1]; byte r = grayValues[_Index + 2]; if (b > 245 && g > 245 && r > 245) { grayValues[_Index] = rin; grayValues[_Index + 1] = gin; grayValues[_Index + 2] = bin; } _Index += 3; } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); bmp.UnlockBits(bmpData); } public static void FillBackgrounPoint(Bitmap bmp, Color background) { System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = bmpData.Stride * bmp.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int _Index = 0; for (int z = 0; z != bmp.Height; z++) { _Index = z * bmpData.Stride; bool jump = false; for (int i = 0; i != bmp.Width; i++) { byte b = grayValues[_Index]; byte g = grayValues[_Index + 1]; byte r = grayValues[_Index + 2]; if (b < background.B && g < background.G && r < background.R) { if (!jump) { grayValues[_Index] = background.B; grayValues[_Index + 1] = background.G; grayValues[_Index + 2] = background.R; } } else { if (!jump) { jump = true; } } _Index += 3; } } ptr = bmpData.Scan0; _Index = 0; for (int z = 0; z != bmp.Height; z++) { _Index = (z + 1) * bmpData.Stride - 3; bool jump = false; for (int i = bmp.Width - 1; i > -1; i--) { byte b = grayValues[_Index]; byte g = grayValues[_Index + 1]; byte r = grayValues[_Index + 2]; if (b < background.B && g < background.G && r < background.R) { if (!jump) { grayValues[_Index] = background.B; grayValues[_Index + 1] = background.G; grayValues[_Index + 2] = background.R; } } else { if (!jump) { jump = true; } } _Index -= 3; } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); bmp.UnlockBits(bmpData); } public static void FillRedPoint(Bitmap bmp, Color color) { System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = bmpData.Stride * bmp.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int _Index = 0; for (int z = 0; z != bmp.Height; z++) { _Index = z * bmpData.Stride; for (int i = 0; i != bmp.Width; i++) { byte b = grayValues[_Index]; byte g = grayValues[_Index + 1]; byte r = grayValues[_Index + 2]; if (b == color.B && g == color.G && r == color.R) { grayValues[_Index] = 0; grayValues[_Index + 1] = 0; grayValues[_Index + 2] = 255; } _Index += 3; } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); bmp.UnlockBits(bmpData); } private static Point QueryFirstPoint(Bitmap bmp, Color color) { Point pt = new Point(-1, -1); System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = bmpData.Stride * bmp.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int _Index = 0; for (int z = 0; z != bmp.Height; z++) { _Index = z * bmpData.Stride; for (int i = 0; i != bmp.Width; i++) { byte b = grayValues[_Index]; byte g = grayValues[_Index + 1]; byte r = grayValues[_Index + 2]; if (b == color.B && g == color.G && r == color.R) { pt.X = i; pt.Y = z; break; } _Index += 4; } if (pt.X > 0) break; } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); bmp.UnlockBits(bmpData); return pt; } private static Rectangle FloodFill(Bitmap src, Point location, Color color, Color fillColor) { Rectangle rect = new Rectangle(10000, 10000, 0, 0); int w = src.Width; int h = src.Height; Stack fillPoints = new Stack(w * h); System.Drawing.Imaging.BitmapData bmpData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = bmpData.Stride * src.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); byte[] temp = (byte[])grayValues.Clone(); if (location.X < 0 || location.X >= w || location.Y < 0 || location.Y >= h) throw new Exception("location error"); fillPoints.Push(new Point(location.X, location.Y)); int[,] mask = new int[w, h]; while (fillPoints.Count > 0) { Point p = fillPoints.Pop(); if (p.X < rect.X) { rect.X = p.X; } if (p.Y < rect.Y) { rect.Y = p.Y; } if (p.X > rect.Width) { rect.Width = p.X; } if (p.Y > rect.Height) { rect.Height = p.Y; } mask[p.X, p.Y] = 1; temp[4 * p.X + p.Y * stride] = (byte)fillColor.B; temp[4 * p.X + 1 + p.Y * stride] = (byte)fillColor.G; temp[4 * p.X + 2 + p.Y * stride] = (byte)fillColor.R; temp[4 * p.X + 3 + p.Y * stride] = (byte)fillColor.A; if (p.X > 0 && temp[4 * (p.X - 1) + 2 + p.Y * stride] == color.R && mask[p.X - 1, p.Y] != 1) { temp[4 * (p.X - 1) + p.Y * stride] = (byte)fillColor.B; temp[4 * (p.X - 1) + 1 + p.Y * stride] = (byte)fillColor.G; temp[4 * (p.X - 1) + 2 + p.Y * stride] = (byte)fillColor.R; temp[4 * (p.X - 1) + 3 + p.Y * stride] = (byte)fillColor.A; fillPoints.Push(new Point(p.X - 1, p.Y)); mask[p.X - 1, p.Y] = 1; } if (p.X < w - 1 && temp[4 * (p.X + 1) + 2 + p.Y * stride] == color.R && mask[p.X + 1, p.Y] != 1) { temp[4 * (p.X + 1) + p.Y * stride] = (byte)fillColor.B; temp[4 * (p.X + 1) + 1 + p.Y * stride] = (byte)fillColor.G; temp[4 * (p.X + 1) + 2 + p.Y * stride] = (byte)fillColor.R; temp[4 * (p.X + 1) + 3 + p.Y * stride] = (byte)fillColor.A; fillPoints.Push(new Point(p.X + 1, p.Y)); mask[p.X + 1, p.Y] = 1; } if (p.Y > 0 && temp[4 * p.X + 2 + (p.Y - 1) * stride] == color.R && mask[p.X, p.Y - 1] != 1) { temp[4 * p.X + (p.Y - 1) * stride] = (byte)fillColor.B; temp[4 * p.X + 1 + (p.Y - 1) * stride] = (byte)fillColor.G; temp[4 * p.X + 2 + (p.Y - 1) * stride] = (byte)fillColor.R; temp[4 * p.X + 3 + (p.Y - 1) * stride] = (byte)fillColor.A; fillPoints.Push(new Point(p.X, p.Y - 1)); mask[p.X, p.Y - 1] = 1; } if (p.Y < h - 1 && temp[4 * p.X + 2 + (p.Y + 1) * stride] == color.R && mask[p.X, p.Y + 1] != 1) { temp[4 * p.X + (p.Y + 1) * stride] = (byte)fillColor.B; temp[4 * p.X + 1 + (p.Y + 1) * stride] = (byte)fillColor.G; temp[4 * p.X + 2 + (p.Y + 1) * stride] = (byte)fillColor.R; temp[4 * p.X + 3 + (p.Y + 1) * stride] = (byte)fillColor.A; fillPoints.Push(new Point(p.X, p.Y + 1)); mask[p.X, p.Y + 1] = 1; } } fillPoints.Clear(); grayValues = (byte[])temp.Clone(); System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); src.UnlockBits(bmpData); rect.Width = rect.Width - rect.X; rect.Height = rect.Height - rect.Y; return rect; } } }