Selenium Screenshot Comparison in Java

Home/Selenium/Selenium Screenshot Comparison in Java

Selenium Screenshot Comparison in Java

To verify that a web application really does what it is supposed to do, sometimes it is not enough to use the built in functions of Selenium. In some cases you don’t just want to know whether Text “xyz” exists or HTML-element-abc is present. You really want to know whether your website looks like you want it to. In most cases you don’t care if there are a few pixels that differ, so you don’t want an exact screenshot comparison but a fuzzy screenshot comparison.

The Selenium WebDriver offers a built in function to take screenshots. This example is from stackoverflow:

WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));

What Selenium doesn’t offer out of the box is a function to compare two screenshots in order to know whether something has changed or not. We wrote our own Java-Library to do this fuzzy screenshot comparison for us. We do not provide any support for this library, but feel free to download and use it as it is:

Download:

image-comparison-1.0.jar 2015-06-23

Basic usage example:

import java.io.IOException;
import org.frontendtest.components.ImageComparison;

public class RunComparison {
	public static void main(String
[] args) throws IOException { String imgOriginal = "original.jpg"; String imgToCompareWithOriginal = "new_screenshot.jpg"; String imgOutputDifferences = "new_screenshot_with_changes.jpg"; ImageComparison imageComparison = new ImageComparison(10,10,0.05); if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences)) System.out.println("Images are fuzzy-equal."); else System.out.println("Images are not fuzzy-equal."); } }

What it does (simplified):

  1. First the two images that should be compared are divided in squares with the width and height, that you defined in the constructor.
  2. For every square in each image an average RGB-Value is calculated.
  3. If the average RGB-Values of the corresponding squares differ more than the threshold that you defined in the constructor (0.05 = 5%), the function fuzzyEqual(…) will return false.
  4. If you passed a path to save an image with the found differences a copy will be save at this path with all the differences marked with red squares.
  5. Note: The sensitivity of the fuzzy-equal-test will be influenced by the defined threshold as well as the size of the squares!

Here are some examples of the comparison results:

We will compare these two images:

Original for Comparison

Original

New Screenshot

New Screenshot

Here are the results:

Square: 10x10pix   Threshold: 10% (0,10)

Square: 10x10pix Threshold: 10% (0,10)

Square: 10x10pix Threshhold: 5% (0.05)

Square: 10x10pix Threshhold: 5% (0.05)

Square: 10x10pix Threshhold: 1% (0.01)

Square: 10x10pix Threshhold: 1% (0.01)

Square: 30x30pix Threshold: 1% (0.01)

Square: 30x30pix Threshold: 1% (0.01)

E.g. comparing these images with square-size 30x30pix and a threshold of 5% (0.05) will tell you that the images are fuzzy-equal!

License:

The MIT License (MIT)

Copyright © 2015 Nils Schütte

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

 

This library makes use of the Thumbnailator which is already included and also published under the MIT License.

By |June 23rd, 2015|Selenium|20 Comments

20 Comments

  1. Arjun April 27, 2016 at 2:51 pm - Reply

    the same steps i have followed and it is throwing exception as below,

    Exception in thread “main” java.lang.NoClassDefFoundError: net/coobird/thumbnailator/Thumbnails
    at org.frontendtest.components.ImageComparison.adaptImageSize(ImageComparison.java:105)
    at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:36)
    at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
    at efWebDriver.ImageComparisionTest.main(ImageComparisionTest.java:38)
    Caused by: java.lang.ClassNotFoundException: net.coobird.thumbnailator.Thumbnails
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    … 4 more

  2. Nils April 28, 2016 at 6:16 pm - Reply

    Hi Arjun, if you post your code or send a message with your code, I will have a look at it.

  3. Parul Shukla May 3, 2016 at 9:01 pm - Reply

    String imgOriginal = “expected.png”;
    String imgToCompareWithOriginal = “Actual.png”;
    String imgOutputDifferences = “diffImage.png”;

    ImageComparison imageComparison = new ImageComparison(10,10,0.05);

    if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences))
    System.out.println(“Images are fuzzy-equal.”);
    else
    System.out.println(“Images are not fuzzy-equal.”);

  4. Anand May 16, 2016 at 6:15 pm - Reply

    I also got the same exception, please look in my code once, I will be very thankful.

    package Day1;

    import java.io.IOException;
    import org.frontendtest.components.ImageComparison;

    public class RunComparison {
    public static void main(String[] args) throws IOException {
    String imgOriginal = “D:\\JAVA\\Programs\\Helios\\src\\Image1.jpg”;
    String imgToCompareWithOriginal = “D:\\JAVA\\Programs\\Helios\\src\\Image2.jpg”;
    String imgOutputDifferences = “D:\\JAVA\\Programs\\Helios\\src\\new_screenshot_with_changes.jpg”;

    ImageComparison imageComparison = new ImageComparison(10,10,0.05);

    if(imageComparison.fuzzyEqual(imgOriginal,imgToCompareWithOriginal,imgOutputDifferences))
    System.out.println(“Images are fuzzy-equal.”);
    else
    System.out.println(“Images are not fuzzy-equal.”);
    }
    }

  5. Adithyan M June 8, 2016 at 4:31 pm - Reply

    Even I’m getting same Error. Please solve this

  6. Barbaros Özdemir June 20, 2016 at 10:04 am - Reply

    i get the same error. Below is my code;

    package rs.indoo.selenium.imagecomparison;

    import java.io.File;
    import java.io.IOException;
    import org.apache.commons.io.FileUtils;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.frontendtest.components.ImageComparison;

    public class Inspector {
    public static void main(String[] args) throws IOException {
    compareImages();
    }

    private static void compareImages() throws IOException {

    String imgOriginal = “/home/barbaros/Desktop/original-300×170.jpg”;
    String imgToCompareWithOriginal = “/home/barbaros/Desktop/new_screenshot-300×170.jpg”;
    String imgOutputDifferences = “/home/barbaros/Desktop/original_diff.png”;

    ImageComparison imageComparison = new ImageComparison(10, 10, 0.05);

    if (imageComparison.fuzzyEqual(imgOriginal, imgToCompareWithOriginal,
    imgOutputDifferences))
    System.out.println(“Images are fuzzy-equal.”);
    else
    System.out.println(“Images are not fuzzy-equal.”);

    }
    }

  7. Barbaros Özdemir June 20, 2016 at 12:04 pm - Reply

    me again, ok solved that problem. apparently you need to import the Thumbnailator library even through you claim it is included in image-comparison-1.0.jar. maybe not referenced correctly? anyways thanks for the great work.

  8. Nils June 20, 2016 at 9:14 pm - Reply

    Thanks for posting your work-around for this issue. I will look into it and post a solution as soon as I solved the bug.

  9. nikhil kanojia July 5, 2016 at 10:21 am - Reply

    Awesome, even i solved the problem , by downloading the Thumnailator jar and importing it.
    Thanks for sharing ,,. it solved a heap of problems off my head

    • Jijo August 9, 2016 at 11:27 am - Reply

      Can you please post your code here

  10. nikhil kanojia July 5, 2016 at 10:22 am - Reply

    link for the jar to be downloaded:
    http://www.java2s.com/Code/Jar/t/Downloadthumbnailator042alljar.htm

    import command:
    import net.coobird.*;

  11. raj September 12, 2016 at 2:09 pm - Reply

    Excellent post …Really thanks.

  12. iliyaz November 2, 2016 at 2:24 pm - Reply

    great….

  13. Ripon November 16, 2016 at 12:28 pm - Reply

    I got the same exception:Exception in thread “main” java.lang.NoClassDefFoundError: net/coobird/thumbnailator/Thumbnails
    at org.frontendtest.components.ImageComparison.adaptImageSize(ImageComparison.java:105)
    at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:36)
    at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
    at image_comparison.RunComparison.main(RunComparison.java:15)
    Caused by: java.lang.ClassNotFoundException: net.coobird.thumbnailator.Thumbnails
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    … 4 more

  14. Ripon November 16, 2016 at 12:35 pm - Reply

    The above exception mentioned by me is solved by using “thumbnailator-0.4.4.jar” in class path. The download URL is http://www.java2s.com/Code/Jar/t/Downloadthumbnailator044jar.htm

  15. Thomas Lehmann January 9, 2017 at 10:43 am - Reply

    I’ve checked in your project at GitHub, added Maven and fixed some small issues with it: https://github.com/tholewebgods/image-comparison I could transfer the project to you (and then clone it) if you wish.

    • Valentin February 16, 2017 at 8:16 am - Reply

      Hi ive tried using the class but getting javax.imageio.IIOException: Can’t read input file! when comparing.
      Any idea why? 🙁

      • Valentin February 16, 2017 at 8:45 am - Reply

        Fixed that, my path wasnt correct however now it just hangs when comparing images

  16. Vinicius Kostriuba March 1, 2017 at 7:30 pm - Reply

    Thank you very much.

Leave A Comment

We sell to companies only. All prices are quoted as monthly fees and net of the statutory value-added tax, if not otherwise described.