简体   繁体   中英

How do I find a image on the screen and get the mouse coordinates?

I want to find the image on the screen and get the x,y coordinates if it matched on the screen. I already know how to move the mouse and click using this x,y coordinates.

EG: I want to give icon image and the code will get a screenshot of desktop and find the image, move mouse.

The following code works, but if I change the resolution of the screen I have to get the image (bmpMatch) again.

    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;

    }

is there anyway I can give any size of image, and get it search from the desktop screenshot.

I was looking for exactly this, thank you very much! Regarding your question, although I don't understand the code well, it worked for me to change the increment in the for, instead of incrementing from 3 to 3, I put it from 1 to 1, it worked for me to find the coordinates in different resolution with the same image

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;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM