0

I'd like to make my Java program compare the actual screen with a picture (screenshot).

I don't know if it's possible, but I have seen it in Jitbit (a macro recorder) and I would like to implement it myself. (Maybe with that example you understand what I mean).

Thanks

----edit----- In other words, is it possible to check if an image is showing in? To find and compare that pixels in the screen?

pabloFdz
  • 157
  • 1
  • 11

4 Answers4

2

You may try aShot: documentation link

1) aShot can ignore areas you mark with special color.

2) aShot can provide image which display difference between images.

private void compareTowImages(BufferedImage expectedImage, BufferedImage actualImage) {
    ImageDiffer imageDiffer = new ImageDiffer();
    ImageDiff diff = imageDiffer
            .withDiffMarkupPolicy(new PointsMarkupPolicy()
                    .withDiffColor(Color.YELLOW))
            .withIgnoredColor(Color.MAGENTA)
            .makeDiff(expectedImage, actualImage);

    // areImagesDifferent will be true if images are different, false - images the same
    boolean areImagesDifferent = diff.hasDiff();
    if (areImagesDifferent) {
        // code in case of failure 
    } else {
        // Code in case of success
    }
}

To save image with differences:

private void saveImage(BufferedImage image, String imageName) {
    // Path where you are going to save image
    String outputFilePath = String.format("target/%s.png", imageName);
    File outputFile = new File(outputFilePath);
    try {
        ImageIO.write(image, "png", outputFile);
    } catch (IOException e) {
        // Some code in case of failure
    }
}
Max Kuznietsov
  • 135
  • 1
  • 6
1

You can do this in two steps:

  1. Create a screenshot using awt.Robot

    BufferedImage image = new Robot().createScreenCapture(new Rctangle(Toolkit.getDefaultToolkit().getScreenSize()));
    ImageIO.write(image, "png", new File("/screenshot.png"));
    
  2. Compare the screenshots using something like that: How to check if two images are similar or not using openCV in java?

Community
  • 1
  • 1
aphex
  • 3,372
  • 2
  • 28
  • 56
  • The point is that I don't only want to compare them. I want to know if the taken screenshot contains the first one. – pabloFdz Dec 18 '13 at 16:40
1

Have a look at Sikuli project. Their automation engine is based on image comparison.

I guess, internally they are still using OpenCV for calculating image similarity, but there are plenty of OpenCV Java bindings like this, which allow to do so from Java.

Project source code is located here: https://github.com/sikuli/sikuli

Michael Spector
  • 36,723
  • 6
  • 60
  • 88
  • That was what I was looking for, I'm going to see how can I get the code or add functionalities to my program. – pabloFdz Dec 18 '13 at 17:16
1

Ok then, so I found an answer after a few days.

This method takes the screenshot:

public static void takeScreenshot() {
        try {
            BufferedImage image = new Robot().createScreenCapture(new Rectangle(490,490,30,30));
/* this two first parameters are the initial X and Y coordinates. And the last ones are the increment of each axis*/
            ImageIO.write(image, "png", new File("C:\\Example\\Folder\\capture.png"));

        } catch (IOException e) {
            e.printStackTrace();
        } catch (HeadlessException e) {
            e.printStackTrace();
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

And this other one will compare the images

public static String compareImage() throws Exception {

// savedImage is the image we want to look for in the new screenshot.
// Both must have the same width and height

    String c1 = "savedImage";
    String c2 = "capture";

    BufferedInputStream in = new BufferedInputStream(new FileInputStream(c1
            + ".png"));
    BufferedInputStream in1 = new BufferedInputStream(new FileInputStream(
            c2 + ".png"));
    int i, j;
    int k = 1;
    while (((i = in.read()) != -1) && ((j = in1.read()) != -1)) {
        if (i != j) {
            k = 0;
            break;
        }
    }

    in.close();
    in1.close();
    if (k == 1) {

        System.out.println("Ok...");
        return "Ok";            

    } else {
        System.out.println("Fail ...");
        return "Fail";
    }
}
pabloFdz
  • 157
  • 1
  • 11
  • That's the same solution that I proposed in my answer. The method will return "OK" only if the both images are the same, but will not work if the second is containing the first image plus other content. – aphex Jan 03 '14 at 16:50
  • In your answer I couldn't see how to take the screenshot from a specific region and comparing that region later. – pabloFdz Jan 04 '14 at 13:06