在另一个位图中查找位图的位置

时间:2016-12-19 23:23:32

标签: c# search bitmap

我正在编写一个程序,它将截取主屏幕,转换为位图,然后几乎用位图“key”搜索屏幕截图的位图。它将位图“key”与整个图片进行比较,找到匹配的位置,将光标移动到位置,然后单击鼠标。我在bmpLogin为空时遇到问题。我在Mopar/Mopar/Resources/bmpLogin.bmp中有我的位图键。我似乎无法找到这个图像进行比较。这是相关的代码。

开始按钮:

    private void startBotButton(object sender, EventArgs e)
    {
        //Screenshot
        //This is where we will be writing the loop for the bot
        Bitmap bmpScreenshot = Screenshot();

        //Set the background of the form the screenshot that was taken
        this.BackgroundImage = bmpScreenshot;
        //Find the node and check if it exists within the screenshot
        Point location;
        bool success = FindBitmap(Properties.Resources.bmpLogin, bmpScreenshot, out location);

        //Check if it found the node in the bitmap
        if (success == false)
        {
            MessageBox.Show("Couldn't find the node");
            return;
        }

        //Move the mouse to the node
        Cursor.Position = location;

        //click
        MouseClick();
    }

截图:

    //Screenshot the screen
    private Bitmap Screenshot()
    {
        //This is where we will store the screenshot
        Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);

        //Create a graphics object so we can draw the screen in the bitmap
        Graphics g = Graphics.FromImage(bmpScreenshot);

        //Copy from screen to bitmap
        g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);

        //Return the screenshot
        return bmpScreenshot;
    }

搜索位图:

    /// <summary>
    /// Find the location of a bitmap within another bitmap and return if it was successfully found
    /// </summary>
    /// <param name="bmpNeedle">The image we want to find</param>
    /// <param name="bmpHaystack">Where we want to search for the image</param>
    /// <param name="location">Where we found the image</param>
    /// <returns>If the bmpNeedle was found successfully</returns>
    private bool FindBitmap(Bitmap bmpNeedle, Bitmap bmpHaystack, out Point location)
    {
        if (bmpNeedle == null || bmpHaystack == null)
        {
            location = new Point();
            return false;
        }
        for (int outerX = 0; outerX < bmpHaystack.Width - bmpNeedle.Width; outerX++)
        {
            for (int outerY = 0; outerY < bmpHaystack.Height - bmpNeedle.Height; outerY++)
            {
                for (int innerX = 0; innerX < bmpNeedle.Width; innerX++)
                {
                    for (int innerY = 0; innerY < bmpNeedle.Height; innerY++)
                    {
                        Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
                        Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);

                        if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
                        {
                            goto notFound;
                        }
                    }
                }
                location = new Point(outerX, outerY);
                return true;
            notFound:
                continue;
            }
        }
        location = Point.Empty;
        return false;
    }

1 个答案:

答案 0 :(得分:0)

害怕我的代表太低而不能发表评论。为非完整答案道歉

你没有足够的答案来更明确地回答(我们需要看看你的资源是如何包含在项目中的)......但是对于你的问题的各种根源,这里有一个很好的答案:{{3 }}

为了提高可读性(以及防止goto),我会考虑将内部两个循环移动到一个函数中。

最后(也可能是最重要的),对于性能,你总是希望在外循环上迭代y,在内循环上迭代x。您应该注意到任何大尺寸图像的显着加速。