1 /* 2 * Copyright (c) 2007, 2017, 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 */ 23 package org.jemmy.image; 24 25 26 import java.awt.image.BufferedImage; 27 import java.io.File; 28 import java.io.IOException; 29 import org.jemmy.Dimension; 30 import org.jemmy.JemmyException; 31 import org.jemmy.control.Wrap; 32 import org.jemmy.env.Environment; 33 import org.jemmy.image.pixel.*; 34 35 36 /** 37 * 38 * @author shura 39 */ 40 public class AWTImage implements Image, WriteableRaster { 41 42 /** 43 * 44 */ 45 public static final String OUTPUT = AWTImage.class.getName() + ".OUTPUT"; 46 public static final String PNG_FILE = ".png"; 47 48 /** 49 * Get the value of imageRoot. The field is used to store images by relative 50 * path within the root. Images should be pointed out by full file names if 51 * the value is null. 52 * 53 * @return the value of imageRoot 54 */ 55 public static File getImageRoot() { 56 ImageStore res = Environment.getEnvironment().getProperty(ImageStore.class); 57 if(!(res instanceof PNGFileImageStore)) { 58 throw new IllegalStateException("Unsupported ImageStore: " + res.getClass().getName()); 59 } 60 return ((PNGFileImageStore)res).getRoot(); 61 } 62 63 /** 64 * Set the value of imageRoot. If null, an image ID should be full path. 65 * 66 * @param imageRoot new value of imageRoot 67 */ 68 public static void setImageRoot(File imageRoot) { 69 Environment.getEnvironment().setProperty(ImageStore.class, new PNGFileImageStore(imageRoot)); 70 } 71 72 /** 73 * Gets comparator to be used by default. 74 * 75 * @see Wrap#waitImage(org.jemmy.image.Image, java.lang.String, 76 * java.lang.String) 77 * @see ImageComparator 78 * @return default comparator 79 */ 80 public static ImageComparator getComparator() { 81 return Environment.getEnvironment().getProperty(ImageComparator.class); 82 } 83 84 /** 85 * Sets comparator to be used by default. 86 * 87 * @see Wrap#waitImage(org.jemmy.image.Image, java.lang.String, 88 * java.lang.String) 89 * @see ImageComparator 90 * @param comparator 91 */ 92 public static void setComparator(ImageComparator comparator) { 93 Environment.getEnvironment().setProperty(ImageComparator.class, comparator); 94 } 95 96 static { 97 Environment.getEnvironment().setPropertyIfNotSet(ImageComparator.class, 98 new BufferedImageComparator(Environment.getEnvironment())); 99 Environment.getEnvironment().setPropertyIfNotSet(ImageStore.class, new PNGFileImageStore()); 100 } 101 102 private final BufferedImage image; 103 104 /** 105 * Creates an instance 106 * 107 * @param img 108 */ 109 public AWTImage(BufferedImage img) { 110 this.image = img; 111 } 112 113 public BufferedImage getTheImage() { 114 return image; 115 } 116 117 /** 118 * Compares using current comparator. 119 * 120 * @see AWTImage#getComparator() 121 * @param img 122 * @return diff image. 123 */ 124 public Image compareTo(Image img) { 125 return getComparator().compare(this, img); 126 } 127 128 /** 129 * Saves to a filesystem. fileName is expected to be a full path, unless 130 * imageRoot is specified. ".png" extension is added automatically if not 131 * specified. 132 * 133 * @see AWTImage#getImageRoot() 134 * @param fileName full or relative file name 135 */ 136 public void save(String fileName) { 137 try { 138 String fullPath = fileName; 139 File imageRoot = getImageRoot(); 140 if (imageRoot != null) { 141 fullPath = imageRoot.getAbsolutePath() + File.separator + fileName; 142 } 143 if (!fullPath.toLowerCase().endsWith(PNG_FILE)) { 144 fullPath += PNG_FILE; 145 } 146 new PNGImageSaver().save(image, fullPath); 147 Environment.getEnvironment().getOutput(OUTPUT).println("Image saved to " + fullPath); 148 } catch (IOException ex) { 149 throw new JemmyException("Unable to save image", ex, fileName); 150 } 151 } 152 153 public Dimension getSize() { 154 return new Dimension(image.getWidth(), image.getHeight()); 155 } 156 157 public void getColors(int x, int y, double[] colors) { 158 int orig = image.getRGB(x, y); 159 int ivalue; 160 for (Raster.Component c : getSupported()) { 161 switch (c) { 162 case ALPHA: 163 ivalue = (orig & 0xFF000000) >>> 0x18; 164 break; 165 case RED: 166 ivalue = (orig & 0xFF0000) >>> 0x10; 167 break; 168 case GREEN: 169 ivalue = (orig & 0xFF00) >>> 0x8; 170 break; 171 case BLUE: 172 ivalue = (orig & 0xFF); 173 break; 174 default: 175 throw new IllegalArgumentException("Unknown color component" + c); 176 } 177 colors[PixelImageComparator.arrayIndexOf(getSupported(), c)] = (double) ivalue / 0xFF; 178 } 179 } 180 181 public void setColors(int x, int y, double[] colors) { 182 int rgb = 0; 183 double value; 184 int ivalue; 185 for (Raster.Component c : getSupported()) { 186 value = colors[PixelImageComparator.arrayIndexOf(getSupported(), c)]; 187 if (value < 0 || value > 1) { 188 throw new IllegalArgumentException("Color component value should be within (0, 1). Gotten: " + value); 189 } 190 ivalue = (int) Math.round(value * 0xFF); 191 if (ivalue > 0xFF) { 192 throw new IllegalStateException("Component value is greater than 0xFF: " + ivalue); 193 } 194 switch (c) { 195 case ALPHA: 196 rgb |= (ivalue << 0x18); 197 break; 198 case RED: 199 rgb |= (ivalue << 0x10); 200 break; 201 case GREEN: 202 rgb |= (ivalue << 0x8); 203 break; 204 case BLUE: 205 rgb |= ivalue; 206 break; 207 default: 208 throw new IllegalArgumentException("Unknown color component: " + c); 209 } 210 } 211 getTheImage().setRGB(x, y, rgb); 212 } 213 214 public Component[] getSupported() { 215 return new Component[]{Component.RED, Component.BLUE, Component.GREEN, Component.ALPHA}; 216 } 217 }