PixelSearch在显示器的某些区域

时间:2017-10-03 20:55:55

标签: c# autoit

所以我试图在给定区域的屏幕中间找到某种模式。我正在使用AutoItX库和PixelSearch方法。

  • 矩形X:1980
  • 矩形Y:630
  • 矩形尺寸X:1240
  • 矩形尺寸Y:180

它没有返回找到模式,但如果我将矩形的线调整为0, 0,则表明已找到该模式。

使用以下脚本:

  public void MonsterScan()
  {
    if(SixStarMax() == true)
    {
        Console.WriteLine("Pattern found");
    }
  }

  public bool SixStarMax()
  {
    Rectangle rect = new Rectangle(1980, 630, 1240, 180);
    autoSumPoint = AutoItX.PixelSearch(rect, 0xF8F0E0); // 0xF8F0E0
    autoSumPoint2 = AutoItX.PixelSearch(rect, 0xB7AD9F); // 0xB7AD9F
    autoSumPoint3 = AutoItX.PixelSearch(rect, 0xCDC6B8); // 0xCDC6B8
    autoSumPoint4 = AutoItX.PixelSearch(rect, 0x949084); // 0x949084

    if (rect.Contains(autoSumPoint2) == true && rect.Contains(autoSumPoint2) == true && rect.Contains(autoSumPoint3) == true && rect.Contains(autoSumPoint4) == true)
    {
      AutoItX.MouseMove(autoSumPoint.X, autoSumPoint.Y);
      return true;
    }
    else
    {
      return false;
    }
  }

编辑:

尝试将坐标调整到我的第一个屏幕,然后我收到错误。

System.AccessViolationException: 'An attempt was made to read or write to protected memory. This often indicates that other memory is damaged. '

2 个答案:

答案 0 :(得分:4)

AutoItX' PixelSearch()a bug。可能的解决方案:

  • 查看它是否已在latest beta中修复。
  • 更改坐标(旧版本已切换X / Y)。
  • 使用PixelGetColor()
  • 找到第三方image search dll

答案 1 :(得分:0)

您可以在没有任何外部库的情况下对其进行编码,并通过内部读取字节来实现快速编码。不要忘记在using语句中包含System.Drawing.Imaging和System.Linq,并使用' Unsafe'进行编译。项目选项中的选项。

public bool SixStarMax()
{
    Rectangle rect = new Rectangle(1980, 630, 1240, 180);

    Bitmap bitmapToScan = GetScreenPart(rect);

    Point?[] autoSumPoints = new Point?[4];

    autoSumPoints[0] = SearchForColor(bitmapToScan, 0xF8F0E0);
    autoSumPoints[1] = SearchForColor(bitmapToScan, 0xB7AD9F);
    autoSumPoints[2] = SearchForColor(bitmapToScan, 0xCDC6B8);
    autoSumPoints[3] = SearchForColor(bitmapToScan, 0x949084);

    //return true if all points return a value
    bool containsAll = autoSumPoints.All(p => p.HasValue);

    if (containsAll) Cursor.Position = autoSumPoints[0].Value;
    return containsAll;
}

public Bitmap GetScreenPart(Rectangle rect)
{
    //initialize bitmap
    Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);

    //fill bitmap
    using (Graphics g = Graphics.FromImage(bmp))
        g.CopyFromScreen(new Point(rect.Left, rect.Top), new Point(rect.Right, rect.Bottom), rect.Size);

    return bmp;
}

public Point? SearchForColor(Bitmap image, uint color)
{
    Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);

    BitmapData data = image.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);

    //works for 32-bit pixel format only
    int ymin = rect.Top, ymax = Math.Min(rect.Bottom, image.Height);
    int xmin = rect.Left, xmax = Math.Max(rect.Right, image.Width) - 1;

    int strideInPixels = data.Stride / 4; //4 bytes per pixel
    unsafe
    {
        uint* dataPointer = (uint*)data.Scan0;
        for (int y = ymin; y < ymax; y++)
            for (int x = xmin; x < xmax; x++)
            {
                //works independently of the data.Stride sign
                uint* pixelPointer = dataPointer + y * strideInPixels + x;
                uint pixel = *pixelPointer;
                bool found = pixel == color;
                if (found)
                {

                    image.UnlockBits(data);
                    return new Point(x, y);

                }
            }
    }
    image.UnlockBits(data);
    return null;
}