1/* 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.netbeans.jemmy.image; 24 25import java.awt.image.BufferedImage; 26 27/** 28 * Compares two images with color mapping defined by {@code ColorModel} 29 * implementation. 30 * 31 * @author Alexandre Iline (alexandre.iline@oracle.com) 32 */ 33public class ColorImageComparator extends StrictImageComparator { 34 35 ColorMap leftMap, rightMap; 36 ImageComparator comparator = null; 37 38 /** 39 * Creates a comparator with a color maps. Object created by this 40 * constructor behaves like {@code StrictImageComparator}. Object 41 * created works faster because it does not create intermediate images for 42 * another comparator. 43 * 44 * @param map Map applied to both left and right images during comparision. 45 */ 46 public ColorImageComparator(ColorMap map) { 47 leftMap = map; 48 rightMap = map; 49 } 50 51 /** 52 * Creates a comparator with {@code map} color mapping. Actual 53 * comparision perfomed by {@code comparator} parameter. 54 * 55 * @param map Map applied to both left and right images during comparision. 56 * @param subComparator comporator to perform a comparision of to images 57 * with mapped colors. 58 */ 59 public ColorImageComparator(ColorMap map, ImageComparator subComparator) { 60 this(map); 61 this.comparator = subComparator; 62 } 63 64 /** 65 * Creates a comparator with two color maps. Object created by this 66 * constructor behaves like {@code StrictImageComparator}. Object 67 * created works faster because it does not create intermediate images for 68 * another comparator. 69 * 70 * @param leftMap Map applied to the left image during comparision. 71 * @param rightMap Map applied to the right image during comparision. 72 */ 73 public ColorImageComparator(ColorMap leftMap, ColorMap rightMap) { 74 this.leftMap = leftMap; 75 this.rightMap = rightMap; 76 } 77 78 /** 79 * Creates a comparator with two color maps. Actual comparision perfomed by 80 * {@code comparator} parameter. 81 * 82 * @param leftMap Map applied to the left image during comparision. 83 * @param rightMap Map applied to the right image during comparision. 84 * @param subComparator comporator to perform a comparision of to images 85 * with mapped colors. 86 */ 87 public ColorImageComparator(ColorMap leftMap, ColorMap rightMap, ImageComparator subComparator) { 88 this(leftMap, rightMap); 89 this.comparator = subComparator; 90 } 91 92 /** 93 * Compares images by {@code ImageComparator} passed into constructor, 94 * or itself if no {@code ImageComparator} was passed, processing both 95 * images by {@code ColorMap} instance before comparision. 96 */ 97 @Override 98 public boolean compare(BufferedImage image1, BufferedImage image2) { 99 if (comparator != null) { 100 return comparator.compare(recolor(image1, leftMap), recolor(image2, rightMap)); 101 } else { 102 return super.compare(image1, image2); 103 } 104 } 105 106 private BufferedImage recolor(BufferedImage src, ColorMap map) { 107 BufferedImage result = new BufferedImage(src.getWidth(), src.getHeight(), src.getType()); 108 for (int x = 0; x < src.getWidth(); x++) { 109 for (int y = 0; y < src.getWidth(); y++) { 110 result.setRGB(x, y, map.mapColor(src.getRGB(x, y))); 111 } 112 } 113 return result; 114 } 115 116 @Override 117 protected final boolean compareColors(int rgb1, int rgb2) { 118 return leftMap.mapColor(rgb1) == rightMap.mapColor(rgb2); 119 } 120 121 /** 122 * Interface to map colors during the comparision. 123 */ 124 public static interface ColorMap { 125 126 /** 127 * Maps one color into another. 128 * 129 * @param rgb an original color. 130 * @return a converted color. 131 */ 132 public int mapColor(int rgb); 133 } 134 135 /** 136 * Turns {@code foreground} color to white, other - to black. 137 */ 138 public static class ForegroundColorMap implements ColorMap { 139 140 int foreground; 141 142 /** 143 * Constructs a ColorImageComparator$ForegroundColorMap object. 144 * 145 * @param foreground Foreground color. 146 */ 147 public ForegroundColorMap(int foreground) { 148 this.foreground = foreground; 149 } 150 151 @Override 152 public int mapColor(int rgb) { 153 return (rgb == foreground) ? 0xffffff : 0; 154 } 155 } 156 157 /** 158 * Turns {@code background} color to black, left others unchanged. 159 */ 160 public static class BackgroundColorMap implements ColorMap { 161 162 int background; 163 164 /** 165 * Constructs a ColorImageComparator$BackgroundColorMap object. 166 * 167 * @param background Background color. 168 */ 169 public BackgroundColorMap(int background) { 170 this.background = background; 171 } 172 173 @Override 174 public int mapColor(int rgb) { 175 return (rgb == background) ? 0 : rgb; 176 } 177 } 178 179} 180