55
66package com .assertthat .selenium_shutterbug .utils .image ;
77
8+ import com .assertthat .selenium_shutterbug .utils .file .FileUtil ;
89import com .assertthat .selenium_shutterbug .utils .web .Coordinates ;
910
1011import java .awt .*;
1112import java .awt .color .ColorSpace ;
1213import java .awt .image .*;
14+ import java .io .File ;
1315
1416/**
1517 * Created by Glib_Briia on 17/06/2016.
@@ -18,6 +20,7 @@ public class ImageProcessor {
1820
1921 private static final int ARCH_SIZE = 10 ;
2022 private static float [] matrix = new float [49 ];
23+ private static double pixelError = Double .MAX_VALUE ;
2124
2225 static {
2326 for (int i = 0 ; i < 49 ; i ++)
@@ -129,6 +132,68 @@ public static boolean imagesAreEquals(BufferedImage image1, BufferedImage image2
129132 return p == 0 || p <= deviation ;
130133 }
131134
135+ /**
136+ * Extends the functionality of imagesAreEqualsWithDiff, but creates a third BufferedImage and applies pixel manipulation to it.
137+ * @param image1 The first image to compare
138+ * @param image2 The second image to compare
139+ * @param pathFileName The output path filename for the third image, if null then is ignored
140+ * @param deviation The upper limit of the pixel deviation for the test
141+ * @return If the test passes
142+ */
143+ public static boolean imagesAreEqualsWithDiff (BufferedImage image1 , BufferedImage image2 , String pathFileName , double deviation ) {
144+ BufferedImage output = new BufferedImage (image1 .getWidth (), image1 .getHeight (), BufferedImage .TYPE_INT_RGB );
145+
146+ int width1 = image1 .getWidth (null );
147+ int width2 = image2 .getWidth (null );
148+ int height1 = image1 .getHeight (null );
149+ int height2 = image2 .getHeight (null );
150+ if ((width1 != width2 ) || (height1 != height2 )) {
151+ throw new UnableToCompareImagesException ("Images dimensions mismatch: image1 - " + width1 + "x" + height1 + "; image2 - " + width2 + "x" + height2 );
152+ }
153+ long diff = 0 ;
154+ long recordedDiff = 0 ; // Records the difference so it can be compared, saves having to do three if statements
155+ for (int y = 0 ; y < height1 ; y ++) {
156+ for (int x = 0 ; x < width1 ; x ++) {
157+ recordedDiff = diff ;
158+
159+ // Grab RGB values of both images, then bit shift and bitwise AND to break them down into R, G and B
160+ int rgb1 = image1 .getRGB (x , y );
161+ int rgb2 = image2 .getRGB (x , y );
162+ int r1 = (rgb1 >> 16 ) & 0xff ;
163+ int g1 = (rgb1 >> 8 ) & 0xff ;
164+ int b1 = (rgb1 ) & 0xff ;
165+ int r2 = (rgb2 >> 16 ) & 0xff ;
166+ int g2 = (rgb2 >> 8 ) & 0xff ;
167+ int b2 = (rgb2 ) & 0xff ;
168+ diff += Math .abs (r1 - r2 );
169+ diff += Math .abs (g1 - g2 );
170+ diff += Math .abs (b1 - b2 );
171+
172+ // If difference > recorded difference, change pixel to red. If zero, set to image 1's original pixel
173+ if (diff > recordedDiff )
174+ output .setRGB (x ,y ,new Color (255 ,0 ,0 ).getRGB () & rgb1 ); // Dark red = original position, Light red is moved to
175+ else
176+ output .setRGB (x ,y ,rgb1 );
177+ }
178+ }
179+ int colourSpaceBytes = 3 ; // RGB is 24 bit, or 3 bytes
180+ double totalPixels = width1 * height1 * colourSpaceBytes ;
181+ pixelError = diff / totalPixels / 255.0 ;
182+
183+ // Write the image as png, with the filename based on the path provided
184+ if (pixelError > 0 )
185+ FileUtil .writeImage (output ,"png" ,new File (pathFileName ));
186+ return pixelError == 0 || pixelError <= deviation ;
187+ }
188+
189+ /**
190+ * Gives back the pixel error set by imagesAreEqualsWithDiff. 'getPixelError' should be called after 'imagesAreEqualsWithDiff.'
191+ * @return pixelError The pixel error
192+ */
193+ public static double getPixelError (){
194+ return pixelError ;
195+ }
196+
132197 public static BufferedImage scale (BufferedImage source , double ratio ) {
133198 int w = (int ) (source .getWidth () * ratio );
134199 int h = (int ) (source .getHeight () * ratio );
0 commit comments