Wednesday, July 20, 2011

Comparing and re-sizing images using Selenium

While automating a web application some of us have to deal with the test to check that an image has been successfully uploaded or not.And that the uploaded image matches with the actual one or not. To automate this test, there are certain things that we need to achieve:

  1. Saving the image that has been uploaded for comparison with the original image.
  2. Handling the re-sizing and re-formatting of the image by the web application itself.
  3. Logic to compare images.

1. Saving the image.
Selenium does not support any direct way to actually store/get an image. But there are other ways like "right-click" and "Save as" option using which you can save the image on firefox and chrome. Once you get an image you can move further with the second step that is checking size of the image.

2. Handling the re-sizing and re-formatting of the image by the web application itself.
Whenever we upload an Image to a web-app it internally re-size and re-format the image while storing or rendering to save space and improve performance. So if you save an uploaded image from your web-app  and want to compare it with the original image, it will fail. The reason being the image that you had downloaded from the web-app has been modified and may not match with the original image in terms of format, size and clarity. The solution to it can be achieved by getting the logic from the development team for re-sizing or re-formatting of image that they use inside their code. You can use then use the same code in you automation test to re-size and re-format your original image and then compare it with the downloaded image to check whether both matches or not.
Following code will give you a general idea on how to re-size an image.

public BufferedImage resize(BufferedImage img, int newW, int newH) {
//Getting the width and height of the given image.  
int w = img.getWidth();
  int h = img.getHeight();
//Creating a new image object with the new width and height and with the old image type
  BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
  Graphics2D g = dimg.createGraphics();
  g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//Creating a graphics image for the new Image.
  g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
  g.dispose();
  return dimg;
 }

3. Logic to compare images.
Once you had completed the above two steps you can go ahead with comparison of the images.
Following is a  java code using which you can actually match two images pixel by pixel.


import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;


public void compareImage() {
  boolean ret = true;
  try {
   original = ImageIO.read(new File(
     "originalFile"));
   copy = ImageIO.read(new File("copyFile"));

   ras1 = original.getData();
   ras2 = copy.getData();
//Comparing the the two images for number of bands,width & height.
   if (ras1.getNumBands() != ras2.getNumBands()
     || ras1.getWidth() != ras2.getWidth()
     || ras1.getHeight() != ras2.getHeight()) {
      ret=false;
   }else{
   // Once the band ,width & height matches, comparing the images.

   search: for (int i = 0; i < ras1.getNumBands(); ++i) {
    for (int x = 0; x < ras1.getWidth(); ++x) {
     for (int y = 0; y < ras1.getHeight(); ++y) {
      if (ras1.getSample(x, y, i) != ras2.getSample(x, y, i)) {
     // If one of the result is false setting the result as false and breaking the loop.
       ret = false;
       break search;
      }
     }
    }
   }
   }
   if (ret == true) {
    System.out.println("Image matches");
   } else {
    System.out.println("Image does not matches");
   }

  } catch (IOException e) {
   System.out.println(e);
  }
 }

11 comments :

Sanjay said...

Whether the image comparison is possible only with the help of coding! Cant it be compared by using any Utilities..
Can i get C# scripts that compares Actual and Expected images..

Varun Menon said...

@Sanjay - Sikuli is one tool using which u can do image comparison. You can use the similar logic shown above in C#. I cant help you with the exact code as I dont knw the coding in C#.

sanjay said...

ven i want to compare group of images with other groups of images and want to find the accuracy of the images.Is there a too l or a program which compares images and produces the accuracy of the images

Varun Menon said...

Try using sikuli: http://sikuli.org/

maheshwar said...

Hi,

For Saving the image(Right Click and Save ImageAs), Im tring with SciTE4AutoIt3 tool, Im not succeed.

Please suggest the right way to Save the image.

Varun Menon said...

I normally dont suggest using AutoIT as it is dependent OS.
You can try getting the source( src attribute) for the image you want to download and try something that is mentione in following link:
http://stackoverflow.com/questions/5882005/how-to-download-image-from-any-web-page-in-java

maheshwar said...

Thanks you for response, it is working now.

Chandru said...

Hi,

From Where Original and copy will be taken?




Varun Menon said...

Original file is the file that is being uploaded or the base image for comparison. Copy image is the image that is downloaded for the web-app.

Unknown said...

Hi, 'm new to selenium. While i try to automate some account registration, at the end of the page.. they are asking to enter some text and numbers to prove if 'm a a human. in that scenario, how to automate that. I tried to check that.. that is the image. How to get text from that.. any idea.. how this scenario can be handled in selenium? Please guide me.

Varun Menon said...

The said functionality that you are talking about is called "Captcha". The whole funda of the said feature is to verify that its the human who is working on the said page or form. There is not direct way to automate it.
You can talk to your developers to have a feature flag in place which when set will give you the same captcha always or a captcha whose locator can give you the info about the text on captcha. This falg you can set and use in your test environment where as in your production build you can disable it.

Post a Comment