/* * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.jemmy.image; import org.jemmy.Dimension; import org.jemmy.env.Environment; import org.jemmy.env.TestOut; import org.jemmy.image.pixel.ResizeComparator; import java.awt.Graphics2D; import java.awt.image.BufferedImage; /** * Comparator that makes image sizes equal to compare them with other comparator * most of them work only for the images with equal dimensions. * * It is controlled by three parameters:
  • Resize Mode - defines way of * resizing images that are being compared. One of the following constants: * Default value is {@linkplain ResizeMode#PROPORTIONAL_RESIZE}.
  • Resize * Hint - defines the way of images scaling that is specified when {@linkplain java.awt.Image#getScaledInstance(int, int, int) * Image.getScaledInstance()} method is invoked. One of the Image.SCALE_XXX is * expected. Default value is * {@linkplain java.awt.Image#SCALE_DEFAULT SCALE_DEFAULT}.
  • Proportion * Distortion Threshold - defines maximum proportion distortion that is used in {@linkplain ResizeMode#PROPORTIONAL_RESIZE * PROPORTIONAL_RESIZE} mode to deal with cases when rounding and other problems * could cause sizes to be not ideally proportional.

    * Threshold value is applied in the following way: {@code Math.abs(image.getSize() * scale * - size) / image.getSize() > PROPORTION_DISTORTION_THRESHOLD}, where {@code image.getSize()} * is both image dimensions and {@code size} is target width and height (which * is defined as mininum of sizes of two images) and scale is the scale factor * that scales the particular image to fit the width and height. *

    * Default value is 0.02 so as much as 2% of width/height could differ (around 5 * in 0-255 color component values).

  • * * @author mrkam */ public class ResizeImageComparator extends ResizeComparator { /** * Indentifies output where resize details are printed. Output is disabled * by default. * * @see Environment#getOutput(java.lang.String) */ public static final String OUTPUT = ResizeImageComparator.class.getName() + ".OUTPUT"; static { Environment.getEnvironment().setOutput(OUTPUT, TestOut.getNullOutput()); } private final ResizeMode resizeMode; private final int hint; private final double propDistThreshold; /** * Resize Modes * * @see * #ResizeImageComparator(org.jemmy.image.ResizeImageComparator.ResizeMode, * org.jemmy.image.ImageComparator) * @see * #ResizeImageComparator(org.jemmy.image.ResizeImageComparator.ResizeMode, * int, double, org.jemmy.image.ImageComparator) */ public static enum ResizeMode { /** * Images are never resized. Original images are always compared. */ NO_RESIZE, /** * Images are resized only if they have exactly or almost proportional * sizes which is controlled by {@code proportionDistortion} parameter. * If images have different proportions no resize is done and original * images are compared. * * @see * #ResizeImageComparator(org.jemmy.image.ResizeImageComparator.ResizeMode, * int, double, org.jemmy.image.ImageComparator) */ PROPORTIONAL_RESIZE, /** * Images are always resized to match both width and height and then * compared. */ ARBITRARY_RESIZE } /** * Creates ResizeImageComparator with default resize settings:
  • resize * mode: {@linkplain ResizeMode#PROPORTIONAL_RESIZE ResizeMode.PROPORTIONAL_RESIZE}.
  • *
  • proportion distortion threshold: 0.02.
  • resize hint: {@linkplain java.awt.Image#SCALE_DEFAULT Image.SCALE_DEFAULT}.
  • * * @param subComparator comparator to compare images after resize. * @see java.awt.Image#getScaledInstance(int, int, int) * @see ResizeMode * @see ResizeImageComparator */ public ResizeImageComparator(ImageComparator subComparator) { this(ResizeMode.PROPORTIONAL_RESIZE, 0.02, java.awt.Image.SCALE_DEFAULT, subComparator); } /** * Creates ResizeImageComparator with the specified resize mode and default * settings for other parameters:
  • proportion distortion threshold: * 0.02.
  • resize hint: {@linkplain java.awt.Image#SCALE_DEFAULT Image.SCALE_DEFAULT}.
  • * * @param resizeMode resize mode for this comparator. * @param subComparator comparator to compare images after resize. * @see ResizeMode * @see ResizeImageComparator */ public ResizeImageComparator(ResizeMode resizeMode, ImageComparator subComparator) { this(resizeMode, 0.02, java.awt.Image.SCALE_DEFAULT, subComparator); } /** * Creates ResizeImageComparator with the following settings:
  • resize * mode: {@linkplain ResizeMode#PROPORTIONAL_RESIZE ResizeMode.PROPORTIONAL_RESIZE}.
  • *
  • specified proportion distortion threshold.
  • resize hint: {@linkplain java.awt.Image#SCALE_DEFAULT Image.SCALE_DEFAULT}.
  • * * @param propDistThreshold proportion distortion threshold. * @param subComparator comparator to compare images after resize. * @see ResizeImageComparator */ public ResizeImageComparator(double propDistThreshold, ImageComparator subComparator) { this(ResizeMode.PROPORTIONAL_RESIZE, propDistThreshold, java.awt.Image.SCALE_DEFAULT, subComparator); } /** * Creates ResizeImageComparator with specified settings. * * @param resizeMode Resize mode. * @param propDistThreshold Proportion distortion threshold. * @param hint Resize hint. * @param subComparator comparator to compare images after resize. * @see ResizeImageComparator * @see ResizeMode */ public ResizeImageComparator(ResizeMode resizeMode, double propDistThreshold, int hint, ImageComparator subComparator) { super(subComparator, ResizeComparator.Mode.LEFT); this.resizeMode = resizeMode; this.hint = hint; this.propDistThreshold = propDistThreshold; } @Override public Image resize(Image image, Dimension size) { Dimension isize = getSize(image); double scalex = (double) size.width / isize.width; double scaley = (double) size.height / isize.height; switch (resizeMode) { case NO_RESIZE: return image; case PROPORTIONAL_RESIZE: if (Math.abs(scalex - scaley) > propDistThreshold) { return null; } case ARBITRARY_RESIZE: BufferedImage res = new BufferedImage(size.width, size.height, ((AWTImage) image).getTheImage().getType()); java.awt.Image scaled = ((AWTImage) image).getTheImage().getScaledInstance( size.width, size.height, hint); Graphics2D g = res.createGraphics(); g.drawImage(scaled, 0, 0, null); g.dispose(); return new AWTImage(res); default: return null; } } @Override public String getID() { return ResizeImageComparator.class.getName() + "(" + getSubComparator().getID() + ")"; } @Override public Dimension getSize(Image image) { BufferedImage bi = ((AWTImage)image).getTheImage(); return new Dimension(bi.getWidth(), bi.getHeight()); } public ResizeMode getResizeMode() { return resizeMode; } }