0

I am looking to create a program in Visual Studio (C#) which scans the screen for an exact image in an exact location of the screen. I have seen many discussions which involve algorithms to find a "close" image, but mine will be 100% exact; location, size and all.

I have obtained a png from a section of my screen [Image 1] using this code:

private void button1_Click(object sender, EventArgs e)
    {
        //Create a new bitmap.
        var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                       Screen.PrimaryScreen.Bounds.Height);

        // Create a graphics object from the bitmap.
        var gfxScreenshot = Graphics.FromImage(bmpScreenshot);

        // Take the screenshot from the upper left corner to the right bottom corner.
        gfxScreenshot.CopyFromScreen(1555, 950, 
                                    1700, 1010,
                                    Screen.PrimaryScreen.Bounds.Size,
                                    CopyPixelOperation.SourceCopy);

        // Save the screenshot to the specified path that the user has chosen.
        bmpScreenshot.Save("Screenshot.png");
    }

So, basically here is the flowchart of my program on how I want to move forward: 1) create the master png using the above code 2) run loop: create same screenshot using the same procedure as the master png compare master png to new screenshot png and if:match then move on otherwise reiterate loop.

I am very new to programming, but I don't believe this is beyond me, given a little guidance. I have written fairly complicated (in my opinion) VBA and Matlab programs. Any help is greatly appreciated.

Thank You, Sloan

Sloan
  • 13
  • 2

1 Answers1

0

Digging around a bit through Microsoft's documentation, I came up with a rough function that would do something similar to what you want. https://msdn.microsoft.com/en-us/library/hh191601.aspx

This function offers the chance of getting stuck in an endless loop, so you might consider calling it with a timeout from your main. See here for info on synchronous methods with timeouts: Monitoring a synchronous method for timeout

From your main, all you'd have to do is see if it returns true.

static int Main(string[] args)
{
   if (ImageInLocation(left, right, top, bottom)) {
      // do other things
   }

   return 0;
}

The only thing I'm not entirely sure on is how strict you can be with the ColorDifference. Even if the images are identical, any pixel difference with an entirely non-tolerant ColorDifference will come up false. If you know it should work and it's not, perhaps consider increasing the tolerance. Here's some more info on that: https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.uitesting.colordifference.aspx

public bool ImageInLocation(int left, int right, int top, int bottom) {
   bool image_found = false;
   var masterImage = Image.FromFile("path_to_master");

   while (!image_found) {
      // screenshot code above, output to "path_to/Screenshot.jpg"
      var compImage = Image.FromFile("path_to/Screenshot.jpg");

      // note, all zeroes may not be tolerant enough
      var color_diff = new ColorDifference(0, 0, 0, 0); 
      Image diffImage;

      image_found = ImageComparer.Compare(masterImage, compImage, color_diff, out diffImage);
   }

   return true;
}

Good luck! Welcome to the programming community.

Also, if anyone has any suggestions/changes, feel free to edit this. Happy imaging, friends!

Community
  • 1
  • 1