/// <summary> /// Resize the image to the specified width and height. /// 图片等比缩放 /// </summary> /// <param name="image">The image to resize.</param> /// <param name="width">The width to resize to.</param> /// <param name="height">The height to resize to.</param> /// <returns>The resized image.</returns> public static System.Drawing.Bitmap ZoomAutoImage(System.Drawing.Image initImage, int maxWidth, int maxHeight) { //a holder for the result Bitmap result = new Bitmap(maxWidth, maxHeight); //set the resolutions the same to avoid cropping due to resolution differences result.SetResolution(initImage.HorizontalResolution, initImage.VerticalResolution); //use a graphics object to draw the resized image into the bitmap using (Graphics graphics = Graphics.FromImage(result)) { //模版的宽高比例 double templateRate = (double)maxWidth / maxHeight; //原图片的宽高比例 double initRate = (double)initImage.Width / initImage.Height; //原图与模版比例相等,直接缩放 if (templateRate == initRate) { //按模版大小生成最终图片 graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.Clear(Color.White); graphics.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel); } //原图与模版比例不等,裁剪后缩放 else { int x, y, w, h; int twidth = maxWidth; int height = maxHeight; if (initImage.Width > twidth && initImage.Height > height) { w = twidth; h = twidth * initImage.Height / initImage.Width; if (h > height) { h = height; w = height * initImage.Width / initImage.Height; x = (twidth - w) / 2; y = 0; } else { x = 0; y = (height - h) / 2; } } else if (initImage.Width > twidth) { w = twidth; h = twidth * initImage.Height / initImage.Width; x = 0; y = (height - h) / 2; } else if (initImage.Height > height) { h = height; w = height * initImage.Width / initImage.Height; x = (twidth - w) / 2; y = 0; } else { w = initImage.Width; h = initImage.Height; x = (twidth - w) / 2; y = (height - h) / 2; } //按模版大小生成最终图片 graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.Clear(Color.White); graphics.DrawImage(initImage, new Rectangle(x, y, w, h), 0, 0, initImage.Width, initImage.Height, GraphicsUnit.Pixel); } } //return the resulting bitmap return(result); }
/// <summary> /// Resize the image to the specified width and height. /// 指定长宽裁剪 /// 按模版比例最大范围的裁剪图片并缩放至模版尺寸 /// </summary> /// <param name="image">The image to resize.</param> /// <param name="width">The width to resize to.</param> /// <param name="height">The height to resize to.</param> /// <returns>The resized image.</returns> public static System.Drawing.Bitmap CustomImage(System.Drawing.Image initImage, int maxWidth, int maxHeight) { //a holder for the result Bitmap result = new Bitmap(maxWidth, maxHeight); //set the resolutions the same to avoid cropping due to resolution differences result.SetResolution(initImage.HorizontalResolution, initImage.VerticalResolution); //use a graphics object to draw the resized image into the bitmap using (Graphics graphics = Graphics.FromImage(result)) { //模版的宽高比例 double templateRate = (double)maxWidth / maxHeight; //原图片的宽高比例 double initRate = (double)initImage.Width / initImage.Height; //原图与模版比例相等,直接缩放 if (templateRate == initRate) { //按模版大小生成最终图片 graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.Clear(Color.White); graphics.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel); } //原图与模版比例不等,裁剪后缩放 else { //裁剪对象 System.Drawing.Image pickedImage = null; System.Drawing.Graphics pickedG = null; //定位 Rectangle fromR = new Rectangle(0, 0, 0, 0); //原图裁剪定位 Rectangle toR = new Rectangle(0, 0, 0, 0); //目标定位 //宽为标准进行裁剪 if (templateRate > initRate) { //裁剪对象实例化 pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)System.Math.Floor(initImage.Width / templateRate)); pickedG = System.Drawing.Graphics.FromImage(pickedImage); //裁剪源定位 fromR.X = 0; fromR.Y = (int)System.Math.Floor((initImage.Height - initImage.Width / templateRate) / 2); fromR.Width = initImage.Width; fromR.Height = (int)System.Math.Floor(initImage.Width / templateRate); //裁剪目标定位 toR.X = 0; toR.Y = 0; toR.Width = initImage.Width; toR.Height = (int)System.Math.Floor(initImage.Width / templateRate); } //高为标准进行裁剪 else { pickedImage = new System.Drawing.Bitmap((int)System.Math.Floor(initImage.Height * templateRate), initImage.Height); pickedG = System.Drawing.Graphics.FromImage(pickedImage); fromR.X = (int)System.Math.Floor((initImage.Width - initImage.Height * templateRate) / 2); fromR.Y = 0; fromR.Width = (int)System.Math.Floor(initImage.Height * templateRate); fromR.Height = initImage.Height; toR.X = 0; toR.Y = 0; toR.Width = (int)System.Math.Floor(initImage.Height * templateRate); toR.Height = initImage.Height; } //设置质量 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //裁剪 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); //按模版大小生成最终图片 graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.Clear(Color.Transparent); graphics.DrawImage(pickedImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, pickedImage.Width, pickedImage.Height), System.Drawing.GraphicsUnit.Pixel); //释放资源 pickedImage.Dispose(); pickedG.Dispose(); } } //return the resulting bitmap return(result); }
static void Main(string[] args) { Process[] processes = Process.GetProcesses(); Process wzqProcess = null; foreach (var item in processes) { if (item.MainWindowTitle == "五子棋") { Console.WriteLine(item.ProcessName); Console.WriteLine(item.Id); //窗口名 Console.WriteLine(item.MainWindowTitle); Console.WriteLine(item.MainModule.FileName); Console.WriteLine(item.MainModule.FileVersionInfo.FileVersion); Console.WriteLine(item.MainModule.FileVersionInfo.FileDescription); Console.WriteLine(item.MainModule.FileVersionInfo.Comments); Console.WriteLine(item.MainModule.FileVersionInfo.CompanyName); Console.WriteLine(item.MainModule.FileVersionInfo.FileName); //产品名 Console.WriteLine(item.MainModule.FileVersionInfo.ProductName); Console.WriteLine(item.MainModule.FileVersionInfo.ProductVersion); Console.WriteLine(item.StartTime); Console.WriteLine(item.MainWindowHandle); wzqProcess = item; break; } } Bitmap bitmap = CaptureImage.Captuer(wzqProcess); if (bitmap == null) { return; } //bitmap.Save("a.bmp"); //Process.Start("mspaint", "a.bmp"); //左上角 //227 129 //右下角 //721 621 int width = 721 - 227; int height = 621 - 129; int step = width * 15 / 14 / 15; Bitmap wzqBoardImage = new Bitmap(width * 15 / 14, height * 15 / 14); Graphics g = Graphics.FromImage(wzqBoardImage); // // 摘要: // 在指定位置并且按指定大小绘制指定的 System.Drawing.Image 的指定部分。 // // 参数: // image: // 要绘制的 System.Drawing.Image。 // // destRect: // System.Drawing.Rectangle 结构,它指定所绘制图像的位置和大小。 将图像进行缩放以适合该矩形。 // // srcRect: // System.Drawing.Rectangle 结构,它指定 image 对象中要绘制的部分。 // // srcUnit: // System.Drawing.GraphicsUnit 枚举的成员,它指定 srcRect 参数所用的度量单位。 g.DrawImage(bitmap, new Rectangle(0, 0, wzqBoardImage.Width, wzqBoardImage.Height), new Rectangle(227 - step / 2, 129 - step / 2, wzqBoardImage.Width, wzqBoardImage.Height), GraphicsUnit.Pixel); g.Dispose(); //把Bitmap转换成Mat Mat boardMat = BitmapConverter.ToMat(wzqBoardImage); //因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做) Mat blurBoardMat = new Mat(); Cv2.MedianBlur(boardMat, blurBoardMat, 9); //转为灰度图像 Mat grayBoardMat = new Mat(); Cv2.CvtColor(blurBoardMat, grayBoardMat, ColorConversionCodes.BGR2GRAY); //3:霍夫圆检测:使用霍夫变换查找灰度图像中的圆。 CircleSegment[] circleSegments = Cv2.HoughCircles(grayBoardMat, HoughMethods.Gradient, 1, step * 0.4, 70, 30, (int)(step * 0.3), (int)(step * 0.5)); foreach (var circleSegment in circleSegments) { Cv2.Circle(boardMat, (int)circleSegment.Center.X, (int)circleSegment.Center.Y, (int)circleSegment.Radius, Scalar.Red, 1, LineTypes.AntiAlias); } //判断棋子位置,遍历棋盘上的每个位置 int rows = 15; List <Tuple <int, int, int> > chessPointList = new List <Tuple <int, int, int> >(); //计算棋子颜色的阈值 Scalar scalarLower = new Scalar(128, 128, 128); Scalar scalarUpper = new Scalar(255, 255, 255); //行 for (int i = 0; i < rows; i++) { //列 for (int j = 0; j < rows; j++) { //棋盘棋子坐标 Point2f point = new Point2f(j * step + 0.5f * step, i * step + 0.5f * step); foreach (var circleSegment in circleSegments) { //有棋子 if (circleSegment.Center.DistanceTo(point) < 0.5 * step) { //检查棋子的颜色 //以棋子中心为中心点,截取一部分图片(圆内切正方形),来计算图片颜色 //r^2 = a^2 + a^2 //--> a= ((r^2)/2)^-2 double len = Math.Sqrt(circleSegment.Radius * circleSegment.Radius / 2); Rect rect = new Rect((int)(circleSegment.Center.X - len), (int)(circleSegment.Center.Y - len), (int)(len * 2), (int)(len * 2)); Mat squareMat = new Mat(grayBoardMat, rect); //计算颜色 Mat calculatedMat = new Mat(); Cv2.InRange(squareMat, scalarLower, scalarUpper, calculatedMat); float result = 100f * Cv2.CountNonZero(calculatedMat) / (calculatedMat.Width * calculatedMat.Height); chessPointList.Add(new Tuple <int, int, int>(i + 1, j + 1, result < 50 ? 0 : 1)); break; } } } } foreach (var item in chessPointList) { Console.WriteLine($"{item.Item1},{item.Item2},{item.Item3}"); } Cv2.ImShow("boardMat", boardMat); Cv2.WaitKey(); }