前段时间看到别人玩QQ游戏,美女来找茬,突然之间想到自己可以做个小外挂,自动比较两幅图,把不同之处标出来。软件自动化测试和开发简单的游戏外挂很相似。都是控制UI,然后模拟键盘和鼠标操作
思路:
1. 把 "美女找茬“ 中的两幅画截出来。
2. 对比两幅画,把不同之处标出来。
我们只需要图片在屏幕上的坐标和大小就可以截图了,根据分析图片大小在高度:490, 宽度:440 比较合适
截图的方法为:
public static int height = 490;
public static int width = 440;
public static void CaptureScreenToFile(int left, int right, string fileName)
{
Bitmap image = new Bitmap(height, width);
Graphics g = Graphics.FromImage(image);
g.CopyFromScreen(left, right, 0, 0, image.Size);
image.Save(fileName);
}
另外,我们还需要知道图片所在的坐标。 坐标为游戏窗口的坐标+图片在游戏窗口中的位移
为了获取游戏窗口的坐标我们需要使用2个Win32API函数
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
public Win32API.RECT Pos = new Win32API.RECT();
public void SetPos()
{
IntPtr window = Win32API.FindWindow("#32770", "大家来找茬");
Win32API.GetWindowRect(window, ref Pos);
}
调用SetPos()方法后,就能获取游戏窗口的位置,保存在Pos里。
然后我们截2张图
CaptureScreenToFile(12 + Pos.left, 196 + Pos.top, firstImage);
CaptureScreenToFile(521 + Pos.left, 196 + Pos.top, secondImage);
最后一步就是比较2副图片的不同了, 很简单,逐个像素比较,不同的就用红色表示出来
public static void Compare(string firstImagePath, string secondImagePath, string DifImagePath)
{
Bitmap firstImage = new Bitmap(firstImagePath, true);
Bitmap secondImage = new Bitmap(secondImagePath, true);
Bitmap thirdImage = new Bitmap(height, width);
string firstPixel;
string secondPixel;
if (firstImage.Width == secondImage.Width && firstImage.Height == secondImage.Height)
{
for (int i = 0; i < firstImage.Width; i++)
{
for (int j = 0; j < firstImage.Height; j++)
{
firstPixel = firstImage.GetPixel(i, j).ToString();
secondPixel = secondImage.GetPixel(i, j).ToString();
if (firstPixel != secondPixel)
{
thirdImage.SetPixel(i, j, Color.Red);
}
else
{
thirdImage.SetPixel(i, j, firstImage.GetPixel(i, j));
}
}
}
}
firstImage.Dispose();
secondImage.Dispose();
thirdImage.Save(DifImagePath);
thirdImage.Dispose();
}
运行效果: