You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
14 KiB

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace GummingCommon
{
public class ImageDetectService
{
public static List<Rectangle> QueryRects(Bitmap srcBitmap, Color color, Color fillColor)
{
List<Rectangle> rects = new List<Rectangle>();
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<Point> fillPoints = new Stack<Point>(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;
}
}
}