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