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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.jemmy.image; 26 27 28 import java.awt.image.BufferedImage; 29 import java.io.File; 30 import java.io.IOException; 31 import org.jemmy.Dimension; 32 import org.jemmy.JemmyException; 33 import org.jemmy.control.Wrap; 34 import org.jemmy.env.Environment; 35 import org.jemmy.image.pixel.*; 36 37 38 /** 39 * @author shura 40 */ 41 public class AWTImage implements Image, WriteableRaster { 42 43 public static final String OUTPUT = AWTImage.class.getName() + ".OUTPUT"; 44 public static final String PNG_FILE = ".png"; 45 46 /** 47 * Get the value of imageRoot. The field is used to store images by relative 48 * path within the root. Images should be pointed out by full file names if 49 * the value is null. 50 * 51 * @return the value of imageRoot 52 */ 53 public static File getImageRoot() { 54 ImageStore res = Environment.getEnvironment().getProperty(ImageStore.class); 55 if(!(res instanceof PNGFileImageStore)) { 56 throw new IllegalStateException("Unsupported ImageStore: " + res.getClass().getName()); 57 } 58 return ((PNGFileImageStore)res).getRoot(); 59 } 60 61 /** 62 * Set the value of imageRoot. If null, an image ID should be full path. 63 * 64 * @param imageRoot new value of imageRoot 65 */ 66 public static void setImageRoot(File imageRoot) { 67 Environment.getEnvironment().setProperty(ImageStore.class, new PNGFileImageStore(imageRoot)); 68 } 69 70 /** 71 * Gets comparator to be used by default. 72 * 73 * @see Wrap#waitImage(org.jemmy.image.Image, java.lang.String, 74 * java.lang.String) 75 * @see ImageComparator 76 * @return default comparator 77 */ 78 public static ImageComparator getComparator() { 79 return Environment.getEnvironment().getProperty(ImageComparator.class); 80 } 81 82 /** 83 * Sets comparator to be used by default. 84 * 85 * @see Wrap#waitImage(org.jemmy.image.Image, java.lang.String, 86 * java.lang.String) 87 * @see ImageComparator 88 * @param comparator todo document 89 */ 90 public static void setComparator(ImageComparator comparator) { 91 Environment.getEnvironment().setProperty(ImageComparator.class, comparator); 92 } 93 94 static { 95 Environment.getEnvironment().setPropertyIfNotSet(ImageComparator.class, 96 new BufferedImageComparator(Environment.getEnvironment())); 97 Environment.getEnvironment().setPropertyIfNotSet(ImageStore.class, new PNGFileImageStore()); 98 } 99 100 private BufferedImage image; 101 102 public AWTImage(BufferedImage img) { 103 this.image = img; 104 } 105 106 public BufferedImage getTheImage() { 107 return image; 108 } 109 110 /** 111 * Compares using current comparator. 112 * 113 * @see AWTImage#getComparator() 114 * @param img todo document 115 * @return diff image. 116 */ 117 public Image compareTo(Image img) { 118 return getComparator().compare(this, img); 119 } 120 121 /** 122 * Saves to a filesystem. fileName is expected to be a full path, unless 123 * imageRoot is specified. ".png" extension is added automatically if not 124 * specified. 125 * 126 * @see AWTImage#getImageRoot() 127 * @param fileName full or relative file name 128 */ 129 public void save(String fileName) { 130 try { 131 String fullPath = fileName; 132 File imageRoot = getImageRoot(); 133 if (imageRoot != null) { 134 fullPath = imageRoot.getAbsolutePath() + File.separator + fileName; 135 } 136 if (!fullPath.toLowerCase().endsWith(PNG_FILE)) { 137 fullPath += PNG_FILE; 138 } 139 new PNGImageSaver().save(image, fullPath); 140 Environment.getEnvironment().getOutput(OUTPUT).println("Image saved to " + fullPath); 141 } catch (IOException ex) { 142 throw new JemmyException("Unable to save image", ex, fileName); 143 } 144 } 145 146 public Dimension getSize() { 147 return new Dimension(image.getWidth(), image.getHeight()); 148 } 149 150 public void getColors(int x, int y, double[] colors) { 151 int orig = image.getRGB(x, y); 152 int ivalue; 153 for (Raster.Component c : getSupported()) { 154 switch (c) { 155 case ALPHA: 156 ivalue = (orig & 0xFF000000) >>> 0x18; 157 break; 158 case RED: 159 ivalue = (orig & 0xFF0000) >>> 0x10; 160 break; 161 case GREEN: 162 ivalue = (orig & 0xFF00) >>> 0x8; 163 break; 164 case BLUE: 165 ivalue = (orig & 0xFF); 166 break; 167 default: 168 throw new IllegalArgumentException("Unknown color component" + c); 169 } 170 colors[PixelImageComparator.arrayIndexOf(getSupported(), c)] = (double) ivalue / 0xFF; 171 } 172 } 173 174 public void setColors(int x, int y, double[] colors) { 175 int rgb = 0; 176 double value; 177 int ivalue; 178 for (Raster.Component c : getSupported()) { 179 value = colors[PixelImageComparator.arrayIndexOf(getSupported(), c)]; 180 if (value < 0 || value > 1) { 181 throw new IllegalArgumentException("Color component value should be within (0, 1). Gotten: " + value); 182 } 183 ivalue = (int) Math.round(value * 0xFF); 184 if (ivalue > 0xFF) { 185 throw new IllegalStateException("Component value is greater than 0xFF: " + ivalue); 186 } 187 switch (c) { 188 case ALPHA: 189 rgb |= (ivalue << 0x18); 190 break; 191 case RED: 192 rgb |= (ivalue << 0x10); 193 break; 194 case GREEN: 195 rgb |= (ivalue << 0x8); 196 break; 197 case BLUE: 198 rgb |= ivalue; 199 break; 200 default: 201 throw new IllegalArgumentException("Unknown color component: " + c); 202 } 203 } 204 getTheImage().setRGB(x, y, rgb); 205 } 206 207 public Component[] getSupported() { 208 return new Component[]{Component.RED, Component.BLUE, Component.GREEN, Component.ALPHA}; 209 } 210 }