1818/**
1919 * Locator to search elements by image.
2020 * Takes screenshot and finds match using openCV.
21+ * Performs screenshot scaling if devicePixelRatio != 1.
2122 * Then finds elements by coordinates using javascript.
2223 */
2324public class ByImage extends By {
2425 private static boolean wasLibraryLoaded = false ;
2526 private final Mat template ;
26- private final boolean doScaling ;
2727
2828 private static void loadLibrary () {
2929 if (!wasLibraryLoaded ) {
@@ -39,19 +39,8 @@ private static void loadLibrary() {
3939 * @param file image file to locate element by.
4040 */
4141 public ByImage (File file ) {
42- this (file , false );
43- }
44-
45- /**
46- * Constructor accepting image file.
47- *
48- * @param file image file to locate element by.
49- * @param doScaling perform screenshot scaling if devicePixelRatio != 1
50- */
51- public ByImage (File file , boolean doScaling ) {
5242 loadLibrary ();
5343 this .template = Imgcodecs .imread (file .getAbsolutePath (), Imgcodecs .IMREAD_UNCHANGED );
54- this .doScaling = doScaling ;
5544 }
5645
5746 /**
@@ -60,19 +49,8 @@ public ByImage(File file, boolean doScaling) {
6049 * @param bytes image bytes to locate element by.
6150 */
6251 public ByImage (byte [] bytes ) {
63- this (bytes , false );
64- }
65-
66- /**
67- * Constructor accepting image file.
68- *
69- * @param bytes image bytes to locate element by.
70- * @param doScaling perform screenshot scaling if devicePixelRatio != 1
71- */
72- public ByImage (byte [] bytes , boolean doScaling ) {
7352 loadLibrary ();
7453 this .template = Imgcodecs .imdecode (new MatOfByte (bytes ), Imgcodecs .IMREAD_UNCHANGED );
75- this .doScaling = doScaling ;
7654 }
7755
7856 @ Override
@@ -82,21 +60,14 @@ public String toString() {
8260
8361 @ Override
8462 public List <WebElement > findElements (SearchContext context ) {
85- byte [] screenshotBytes = getScreenshot (context );
86- Mat source = Imgcodecs .imdecode (new MatOfByte (screenshotBytes ), Imgcodecs .IMREAD_UNCHANGED );
87- long devicePixelRatio = (long ) AqualityServices .getBrowser ().executeScript (JavaScript .GET_DEVICE_PIXEL_RATIO );
88- if (devicePixelRatio != 1 && doScaling ) {
89- int scaledWidth = (int ) (source .width () / devicePixelRatio );
90- int scaledHeight = (int ) (source .height () / devicePixelRatio );
91- Imgproc .resize (source , source , new Size (scaledWidth , scaledHeight ), 0 , 0 , Imgproc .INTER_AREA );
92- }
63+ Mat source = getScreenshot (context );
9364 Mat result = new Mat ();
9465 Imgproc .matchTemplate (source , template , result , Imgproc .TM_CCOEFF_NORMED );
9566
9667 float threshold = 1 - AqualityServices .getConfiguration ().getVisualizationConfiguration ().getDefaultThreshold ();
9768 Core .MinMaxLocResult minMaxLoc = Core .minMaxLoc (result );
9869
99- int matchCounter = ( result .width () - template .width () + 1 ) * (result .height () - template .height () + 1 );
70+ int matchCounter = Math . abs (( result .width () - template .width () + 1 ) * (result .height () - template .height () + 1 ) );
10071 List <Point > matchLocations = new ArrayList <>();
10172 while (matchCounter > 0 && minMaxLoc .maxVal >= threshold ) {
10273 matchCounter --;
@@ -149,11 +120,20 @@ protected static double distanceToPoint(Point matchLocation, WebElement element)
149120 * Takes screenshot from searchContext if supported, or from browser.
150121 *
151122 * @param context search context for element location.
152- * @return captured screenshot as byte array .
123+ * @return captured screenshot as Mat object .
153124 */
154- protected byte [] getScreenshot (SearchContext context ) {
155- return !(context instanceof TakesScreenshot )
156- ? AqualityServices .getBrowser ().getScreenshot ()
157- : ((TakesScreenshot ) context ).getScreenshotAs (OutputType .BYTES );
125+ protected Mat getScreenshot (SearchContext context ) {
126+ byte [] screenshotBytes = context instanceof TakesScreenshot
127+ ? ((TakesScreenshot ) context ).getScreenshotAs (OutputType .BYTES )
128+ : AqualityServices .getBrowser ().getScreenshot ();
129+ boolean isBrowserScreenshot = context instanceof WebDriver || !(context instanceof TakesScreenshot );
130+ Mat source = Imgcodecs .imdecode (new MatOfByte (screenshotBytes ), Imgcodecs .IMREAD_UNCHANGED );
131+ long devicePixelRatio = (long ) AqualityServices .getBrowser ().executeScript (JavaScript .GET_DEVICE_PIXEL_RATIO );
132+ if (devicePixelRatio != 1 && isBrowserScreenshot ) {
133+ int scaledWidth = (int ) (source .width () / devicePixelRatio );
134+ int scaledHeight = (int ) (source .height () / devicePixelRatio );
135+ Imgproc .resize (source , source , new Size (scaledWidth , scaledHeight ), 0 , 0 , Imgproc .INTER_AREA );
136+ }
137+ return source ;
158138 }
159139}
0 commit comments