【问题标题】:How do I find a image on the screen and get the mouse coordinates?如何在屏幕上找到图像并获取鼠标坐标?
【发布时间】:2022-07-07 10:20:56
【问题描述】:

我想在屏幕上找到图像并获取 x,y 坐标(如果它在屏幕上匹配)。我已经知道如何使用这个 x,y 坐标移动鼠标并单击。

例如: 我想给图标图像,代码将获取桌面截图并找到图像,移动鼠标。

以下代码有效,但如果我更改屏幕分辨率,我必须再次获取图像 (bmpMatch)

    private static Rectangle FindImageOnScreen(Bitmap bmpMatch, bool ExactMatch)
    {
        Rectangle rct = Rectangle.Empty;
        try
        {
            Bitmap ScreenBmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics g = Graphics.FromImage(ScreenBmp);
            g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                    Screen.PrimaryScreen.Bounds.Y,
                        0, 0,
                        ScreenBmp.Size,
                        CopyPixelOperation.SourceCopy);


            BitmapData ImgBmd = bmpMatch.LockBits(new Rectangle(0, 0, bmpMatch.Width, bmpMatch.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            BitmapData ScreenBmd = ScreenBmp.LockBits(new Rectangle(0, 0, ScreenBmp.Width, ScreenBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            byte[] ImgByts = new byte[(Math.Abs(ImgBmd.Stride) * bmpMatch.Height) - 1 + 1];
            byte[] ScreenByts = new byte[(Math.Abs(ScreenBmd.Stride) * ScreenBmp.Height) - 1 + 1];

            Marshal.Copy(ImgBmd.Scan0, ImgByts, 0, ImgByts.Length);
            Marshal.Copy(ScreenBmd.Scan0, ScreenByts, 0, ScreenByts.Length);

            bool FoundMatch = false;
            
            int sindx, iindx;
            int spc, ipc;

            int skpx = System.Convert.ToInt32((bmpMatch.Width - 1) / (double)10);
            if (skpx < 1 | ExactMatch)
                skpx = 1;
            int skpy = System.Convert.ToInt32((bmpMatch.Height - 1) / (double)10);
            if (skpy < 1 | ExactMatch)
                skpy = 1;

            for (int si = 0; si <= ScreenByts.Length - 1; si += 3)
            {
                FoundMatch = true;
                for (int iy = 0; iy <= ImgBmd.Height - 1; iy += skpy)
                {
                    for (int ix = 0; ix <= ImgBmd.Width - 1; ix += skpx)
                    {
                        sindx = (iy * ScreenBmd.Stride) + (ix * 3) + si;
                        iindx = (iy * ImgBmd.Stride) + (ix * 3);
                        spc = Color.FromArgb(ScreenByts[sindx + 2], ScreenByts[sindx + 1], ScreenByts[sindx]).ToArgb();
                        ipc = Color.FromArgb(ImgByts[iindx + 2], ImgByts[iindx + 1], ImgByts[iindx]).ToArgb();
                        if (spc != ipc)
                        {
                            FoundMatch = false;
                            iy = ImgBmd.Height - 1;
                            ix = ImgBmd.Width - 1;
                        }
                    }
                }
                if (FoundMatch)
                {
                    double r = si / (double)(ScreenBmp.Width * 3);
                    double c = ScreenBmp.Width * (r % 1);
                    if (r % 1 >= 0.5)
                        r -= 1;
                    rct.X = System.Convert.ToInt32(c);
                    rct.Y = System.Convert.ToInt32(r);
                    rct.Width = bmpMatch.Width;
                    rct.Height = bmpMatch.Height;
                    break;
                }
            }

            bmpMatch.UnlockBits(ImgBmd);
            ScreenBmp.UnlockBits(ScreenBmd);
            //ScreenBmp.Dispose();
            return rct;

        } catch(Exception ex)
        {
           
            Console.Write(ex.Message);
        }
        return rct;

    }

有没有我可以给出任意大小的图片,然后从桌面截图中搜索。

【问题讨论】:

标签: c# image


【解决方案1】:

正好在找这个,非常感谢!关于你的问题,虽然我不太了解代码,但它对我来说改变了for中的增量,而不是从3增加到3,我把它从1变成1,它对我来说找到了坐标同一张图片分辨率不同

private static Rectangle FindImageOnScreen(Bitmap bmpMatch, bool ExactMatch)
{
    Rectangle rct = Rectangle.Empty;
    try
    {
        Bitmap ScreenBmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        Graphics g = Graphics.FromImage(ScreenBmp);
        g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                Screen.PrimaryScreen.Bounds.Y,
                    0, 0,
                    ScreenBmp.Size,
                    CopyPixelOperation.SourceCopy);


        BitmapData ImgBmd = bmpMatch.LockBits(new Rectangle(0, 0, bmpMatch.Width, bmpMatch.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        BitmapData ScreenBmd = ScreenBmp.LockBits(new Rectangle(0, 0, ScreenBmp.Width, ScreenBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

        byte[] ImgByts = new byte[(Math.Abs(ImgBmd.Stride) * bmpMatch.Height) - 1 + 1];
        byte[] ScreenByts = new byte[(Math.Abs(ScreenBmd.Stride) * ScreenBmp.Height) - 1 + 1];

        Marshal.Copy(ImgBmd.Scan0, ImgByts, 0, ImgByts.Length);
        Marshal.Copy(ScreenBmd.Scan0, ScreenByts, 0, ScreenByts.Length);

        bool FoundMatch = false;
        
        int sindx, iindx;
        int spc, ipc;

        int skpx = System.Convert.ToInt32((bmpMatch.Width - 1) / (double)10);
        if (skpx < 1 | ExactMatch)
            skpx = 1;
        int skpy = System.Convert.ToInt32((bmpMatch.Height - 1) / (double)10);
        if (skpy < 1 | ExactMatch)
            skpy = 1;

        for (int si = 0; si <= ScreenByts.Length - 1; si ++) //here modify
        {
            FoundMatch = true;
            for (int iy = 0; iy <= ImgBmd.Height - 1; iy += skpy)
            {
                for (int ix = 0; ix <= ImgBmd.Width - 1; ix += skpx)
                {
                    sindx = (iy * ScreenBmd.Stride) + (ix * 3) + si;
                    iindx = (iy * ImgBmd.Stride) + (ix * 3);
                    spc = Color.FromArgb(ScreenByts[sindx + 2], ScreenByts[sindx + 1], ScreenByts[sindx]).ToArgb();
                    ipc = Color.FromArgb(ImgByts[iindx + 2], ImgByts[iindx + 1], ImgByts[iindx]).ToArgb();
                    if (spc != ipc)
                    {
                        FoundMatch = false;
                        iy = ImgBmd.Height - 1;
                        ix = ImgBmd.Width - 1;
                    }
                }
            }
            if (FoundMatch)
            {
                double r = si / (double)(ScreenBmp.Width * 3);
                double c = ScreenBmp.Width * (r % 1);
                if (r % 1 >= 0.5)
                    r -= 1;
                rct.X = System.Convert.ToInt32(c);
                rct.Y = System.Convert.ToInt32(r);
                rct.Width = bmpMatch.Width;
                rct.Height = bmpMatch.Height;
                break;
            }
        }

        bmpMatch.UnlockBits(ImgBmd);
        ScreenBmp.UnlockBits(ScreenBmd);
        //ScreenBmp.Dispose();
        return rct;

    } catch(Exception ex)
    {
       
        Console.Write(ex.Message);
    }
    return rct;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-19
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    相关资源
    最近更新 更多